home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / comm / tcp / AmiTCPtxt_20.lha / doc / maintainertext.txt < prev    next >
Text File  |  1993-08-13  |  98KB  |  2,788 lines

  1.  
  2.  
  3.  
  4.  
  5. Chapter 4
  6.  
  7.  
  8.  
  9. Internal Description
  10.  
  11.  
  12.  
  13. 4.1     Source  File  Structure
  14.  
  15.  
  16. The source tree of AmiTCP/IP is dividedto few main parts:
  17.  
  18.  
  19.  1. Directory sys contains BSD Unix system header files, which are ported
  20.     to the Amiga environment.
  21.  
  22.  
  23.  2. Directory net contains modules for the general networking services.
  24.     They are independent of any particular protocol family.
  25.  
  26.  
  27.  3. Directory netinet contains the modules for the internet (inet)
  28.     protocol family.  IP, ICMP, TCP and UDP are internet protocols.
  29.  
  30.  
  31.  4. Directory kern contains modules, which provide the BSD kernel
  32.     environment for the networking routines.
  33.  
  34.  
  35.  5. Directory api contains the BSD socket compatible shared library API
  36.     code.
  37.  
  38.  
  39.    The filesare briefly described in the following paragraphs.  Note that
  40.  
  41. some of the header files are actually located to the NETINCLUDE:1
  42. directory.
  43.  
  44.  
  45.  
  46. 4.1.1   System Include Files
  47.  
  48.  General Headers
  49.  
  50.  
  51.     sys/cdefs.h  Definitions to harmonize various C language dialects.
  52.  
  53.     sys/param.h  General machine independent parameter definitions.
  54.  
  55.     sys/time.h  Definition of structure timeval.
  56.  
  57.     sys/types.h  Common C type definitions and file descriptorset macros
  58.         for select().
  59.  
  60.  
  61.  BSD Socket API
  62. ________________________________
  63.    1See section 3.1.3 on page 30.
  64.  
  65.  
  66.  
  67.                                       69
  68.  
  69.  
  70. 70    Section 4.1                  AmiTCP/IP                   System Manual
  71.  
  72.  
  73.  
  74.     sys/errno.h  Error code definitions for system functions.
  75.  
  76.     sys/ioctl.h  Definitions for socket IO control.
  77.  
  78.     sys/socket.h  Definitions related to sockets:  types, address
  79.         families, options and prototypes.
  80.  
  81.     sys/uio.h  IO structure definition for sendmsg() and recvmsg()2.
  82.  
  83.  
  84.  BSD Kernel Data Structures
  85.  
  86.  
  87.     sys/domain.h  Domain structure and global domain pointer declarations.
  88.  
  89.     sys/kernel.h  Global kernel variable definitions (used throughoutthe
  90.         kernel).
  91.  
  92.     sys/malloc.h  Defines the bsd_malloc() and bsd_free() functions.
  93.  
  94.     sys/mbuf.h  Mbuf structure definition and inline macros.
  95.  
  96.     sys/protosw.h  Protocol switch structure definition with related
  97.         definitions (options, actions, etc.).
  98.  
  99.     sys/queue.h  General queue data structures.
  100.  
  101.     sys/socketvar.h  Socket structure definition and related utility
  102.         macros.
  103.  
  104.     sys/synch.h  Declarations for tsleep and spl functions.
  105.  
  106.     sys/syslog.h  Logging related definitions.
  107.  
  108.     sys/systm.h  System wide definitions and prototypes.
  109.  
  110.  
  111.  
  112. 4.1.2   Protocol Independent Network Routines
  113.  
  114.  Network Interface
  115.  
  116.  
  117.     net/if.c  General network interface routines.
  118.  
  119.     net/if.h  Defines the interface for network adapter drivers.
  120.  
  121.     net/if_arp.h  General protocol independent ARP structures.
  122.  
  123.     net/if_dl.h  Defines the Link Level sockaddr structure.
  124.  
  125.     net/if_loop.c  Loopback device routines.
  126.  
  127.     net/if_sana.c  Interface module for the SANA-IInetwork adapter
  128.         drivers.
  129.  
  130.     net/if_sana.h  Defines the interface for the SANA-II network adapter
  131.         drivers.
  132.  
  133.     net/if_types.h  Interface type numbers.  Obsolete.
  134.  
  135.     net/netisr.h  and
  136.  
  137.     net/netisr.c  Defines the network input queue scheduling routines.
  138.  
  139.     net/sana2arp.c  ARP routines for Sana-II devices.
  140.  
  141.     net/sana2arp.h  SANA-II private ARP headers.
  142.  
  143.     net/sana2copybuff.c   Buffer management routines called from SANA-II
  144. ________device_driver.__________
  145.  
  146.    2These functions are not implemented in this release of the AmiTCP/IP
  147.  
  148.  
  149. System Manual                   AmiTCP/IP                   Section 4.1    71
  150.  
  151.  
  152.  
  153.     net/sana2errno.h  SANA-II error lists and printing header.
  154.  
  155.     net/sana2request.c   Moduleto handle SANA-II IO Requests.
  156.  
  157.     net/sana2request.h   Inlineroutines to manage different SANA-II IO
  158.         requests.
  159.  
  160.     net/sana2tags.c  Common customization parameters for the sana_softc
  161.         network interface.
  162.  
  163.     net/sana2tags.h  Defines the tags to customize sana_softc network
  164.         interface.
  165.  
  166.     netlib:sana2perror.c   Printing routines for SANA-II error messages.
  167.  
  168.  
  169.  Routing
  170.  
  171.  
  172.     net/radix.c  Routines for searching, adding and removing data items in
  173.         the radix binary tree.
  174.  
  175.     net/radix.h  Defines the radix tree data structures.
  176.  
  177.     net/route.c  General, protocol independent routing functions.
  178.  
  179.     net/route.h  Defines data structures for routing entries,tables and
  180.         statistics.
  181.  
  182.     net/rtsock.c  The socket interface to the routing information.
  183.  
  184.  
  185.  Raw Sockets
  186.  
  187.  
  188.     net/raw_cb.c  Routines to manage the rawprotocol control blocks.
  189.  
  190.     net/raw_cb.h  The raw protocol control block definition.
  191.  
  192.     net/raw_usrreq.c  The raw socket interface to the low level protocols
  193.         and network adapters.
  194.  
  195.  
  196.  
  197. 4.1.3   Internet Protocol Modules
  198.  
  199.  Inet Domain
  200.  
  201.  
  202.     netinet/in.c  Generic Internet addressing routines.
  203.  
  204.     netinet/in.h  Protocol numbers, port conventions, inet address
  205.         definitions.
  206.  
  207.     netinet/in_cksum.c  Calculates checksum for internet protocol headers.
  208.  
  209.     netinet/in_pcb.c  Generic internet protocol routines, binding,
  210.         addressing.
  211.  
  212.     netinet/in_pcb.h  Declares generic internet protocol control block.
  213.  
  214.     netinet/in_proto.c  Defines internet protocol control blocks.
  215.  
  216.     netinet/in_systm.h  Some network byte order type definitions.
  217.  
  218.     netinet/in_var.h  Define an interface address structure for internet.
  219.  
  220.  
  221.  IP, ICMP
  222.  
  223.  
  224.     netinet/icmp_var.h  ICMP statistics.
  225.  
  226.     netinet/ip.h  IP packet header, packet options, timestamp.
  227.  
  228.  
  229. 72    Section 4.1                  AmiTCP/IP                   System Manual
  230.  
  231.  
  232.  
  233.     netinet/ip_icmp.c  Routines to generate, receive and reflect ICMP
  234.         packets.
  235.  
  236.     netinet/ip_icmp.h  ICMP packet structure.
  237.  
  238.     netinet/ip_input.c  IP input, packet reassemble and packet forwarding.
  239.  
  240.     netinet/ip_output.c  IP output, packet fragmenting.
  241.  
  242.     netinet/ip_var.h  Define IP statistics, external IP packet header,
  243.         reassemble queues structures.
  244.  
  245.     netinet/raw_ip.c  Provide a raw interface to the IP protocol.
  246.  
  247.  
  248.  TCP
  249.  
  250.  
  251.     netinet/tcp.h  Define the TCP packet structure.
  252.  
  253.     netinet/tcp_debug.c  TCP debugging routines.
  254.  
  255.     netinet/tcp_debug.h  Header for TCP debugging.
  256.  
  257.     netinet/tcp_fsm.h  TCP Finite State Machine states.
  258.  
  259.     netinet/tcp_input.c  TCP input routines.
  260.  
  261.     netinet/tcp_output.c  TCP output routines.
  262.  
  263.     netinet/tcp_seq.h  TCP sequence numbering.
  264.  
  265.     netinet/tcp_subr.c  Various TCP subroutines for initializing,
  266.         connection maintenance etc.
  267.  
  268.     netinet/tcp_timer.c  TCP timeout routines.
  269.  
  270.     netinet/tcp_timer.h  TCP timing constants.
  271.  
  272.     netinet/tcp_usrreq.c  Process TCP user requests (send, timeout),
  273.         attach, disconnect.
  274.  
  275.     netinet/tcp_var.h  Define TCP control block and TCP statistics.
  276.  
  277.     netinet/tcpip.h  Define the overlaid TCPIP packet header structure.
  278.  
  279.  
  280.  UDP
  281.  
  282.  
  283.     netinet/udp.h  Define the UDP packet structure.
  284.  
  285.     netinet/udp_usrreq.c  Routines to UDP output, input and notification.
  286.  
  287.     netinet/udp_var.h  Define UDPIP packet overlay, UDP statistics.
  288.  
  289.  
  290.  
  291. 4.1.4   BSDKernel Service Modules
  292.  
  293.  BSD Kernel Support
  294.  
  295.  
  296.     kern/amiga_includes.h   Include file which includes all amiga specific
  297.         include files.
  298.  
  299.     kern/amiga_main.c  Main module of the AmiTCP/IP.
  300.  
  301.     kern/amiga_subr.h  Miscellaneous function definitions (usually short
  302.         inline functions).
  303.  
  304.     kern/amiga_time.c  Timer module for the timeout functions.
  305.  
  306.     kern/amiga_time.h  Amiga timer.device related functions.
  307.  
  308.  
  309. System Manual                   AmiTCP/IP                   Section 4.1    73
  310.  
  311.  
  312.  
  313.     kern/kern_malloc.c  Malloc & free related functions.
  314.  
  315.     kern/kern_synch.c  tsleep and spl function definitions.
  316.  
  317.     kern/uipc_mbuf.c  Mbuf functions.
  318.  
  319.  
  320.  Socket Level Functions
  321.  
  322.  
  323.     kern/uipc_domain.c  Domain functions, especially pfslowtimo() and
  324.         pffasttimo().
  325.  
  326.     kern/uipc_socket.c  Higher level so-level functions (socreate(),
  327.         sobind() etc.).
  328.  
  329.     kern/uipc_socket2.c  Lower level so-level functions (soisconnecting(),
  330.         soqremque(), sowakeup() etc.).
  331.  
  332.  
  333.  NETTRACE Maintenance Process Support
  334.  
  335.  
  336.     kern/amiga_config.c  Configuration and ARexx command support routines.
  337.  
  338.     kern/amiga_config.h  Defines the structure for configuration
  339.         variables.
  340.  
  341.     kern/amiga_cstat.c  Query support routines.
  342.  
  343.     kern/amiga_log.c  Functions for initialization of log task and code
  344.         for task itself.
  345.  
  346.     kern/amiga_log.h  Header file for logging functions.
  347.  
  348.     kern/amiga_netdb.c  Network database parsing and support functions.
  349.  
  350.     kern/amiga_netdb.h  Declares the network database structures and
  351.         types.
  352.  
  353.     kern/amiga_rexx.c  Arexx-interface.
  354.  
  355.     kern/amiga_rexx.h  Arexx-interface definitions.
  356.  
  357.     kern/config_var.awk  Awk script to generate both code and
  358.         documentation from the file kern/variables.src.
  359.  
  360.     kern/subr_prf.c  Interfaces for (s)printf(), panic() and log()
  361.  
  362.     kern/variables.src   Definition and documentation for configuration
  363.         variables
  364.  
  365.  
  366.  
  367. 4.1.5   BSDSocket API
  368.  
  369.  Shared Library Interface
  370.  
  371.  
  372.     api/allocdatabuffer.c   Client data buffer allocation functions.
  373.  
  374.     api/allocdatabuffer.h   Client data buffer allocation definitions.
  375.  
  376.     api/amiga_api.c  Contains API initialization and deinitialization
  377.         functions and data.  Opening and Closing of the AmiTCP/IP socket
  378.         library bases.
  379.  
  380.     api/amiga_api.h  Description of the SocketBase structure (forinternal
  381.         AmiTCP/IP use only), and some inline functions relatedto the API
  382.         functionality.
  383.  
  384.  
  385. 74    Section 4.1                  AmiTCP/IP                   System Manual
  386.  
  387.  
  388.  
  389.     api/amiga_libcallentry.h   Included in every module which defines
  390.         AmiTCP/IP socket library calls.
  391.  
  392.     api/amiga_libtables.c   Exec library base list and AmiTCP/IP socket
  393.         library function tables for MakeLibrary().
  394.  
  395.     api/amiga_raf.h  Compiler dependent macros for Register Argument
  396.         Functions.
  397.  
  398.     api/apicalls.h  Includes either api/apicalls_gnuc.h or
  399.         api/apicalls_sasc.h.
  400.  
  401.     api/apicalls_gnuc.h  Inline functions for internal API calls for GNUC.
  402.  
  403.     api/apicalls_sasc.h  Inline functions for internal API calls for SASC.
  404.  
  405.  API Functions
  406.  
  407.     api/amiga_generic.c  General Unix system calls related to file
  408.         descriptors ported for AmiTCP/IP socket library.  There are also
  409.         some Amiga specific extensions to the BSD Unix system calls in
  410.         this module.
  411.  
  412.     api/amiga_libcalls.c  Inet library functions (link library in Unix
  413.         system).  These inet functions are provided as a part of the
  414.         AmiTCP/IP socket library.
  415.  
  416.     api/amiga_syscalls.c  Standard BSD style socket functions ported to
  417.         the AmiTCP/IP socket library.
  418.  
  419.     api/gethostnamadr.c   Functions that calls resolver in order to obtain
  420.         host information from nameserver.  Calls netdatabase functions if
  421.         information can not be resolved.
  422.  
  423.     api/gethtbynamadr.h   Prototypes for two functions in api/getxbyy.h.
  424.  
  425.     api/getxbyy.c  Host (without nameserver), network, service ja protocol
  426.         query functions (also a link library in unix system).
  427.  
  428.     api/hostbuf.h  Structure definition for host queries and few minor
  429.         netdb stuff.
  430.  
  431.  Resolver Functions
  432.  
  433.     api/arpa_nameser.h  Information for nameserver query.
  434.  
  435.     api/res_comp.c  Routines to translate domain names between
  436.         conventional ascii and the compressed format used in queries.
  437.  
  438.     api/res_debug.c  Functions that output debugging information3
  439.  
  440.     api/res_init.h  Resolver initializer function.  Very simple in
  441.         AmiTCP/IP implementation.
  442.  
  443.     api/res_mkquery.c  Function that forms a domain name query in buffer.
  444.  
  445.     api/res_query.c  Functions to generate query sequence and append
  446.         domains to incomplete hostnames.
  447.  
  448.     api/res_send.c  Function to send and receive query to and from a
  449.         nameserver, respectively.
  450.  
  451.     api/resolv.h  Resolver datatypes, defines, variables and prototypes.
  452. ________________________________
  453.    3If RES_DEBUG defined at compile time
  454.  
  455.  
  456. System Manual                   AmiTCP/IP                   Section 4.2    75
  457.  
  458.  
  459.  
  460. 4.1.6   Miscellaneous Files
  461.  
  462.  
  463.  Makefiles
  464.  
  465.  
  466.     GCCOPTS  Compiler options forthe GCC.
  467.  
  468.     GNUmakefile  Makefile used with GNU make in HP-UX workstations, where
  469.         the source tree is maintained.
  470.  
  471.     SCOPTIONS  Compiler options for the SAS/C 6.x
  472.  
  473.     Smakefile  Makefile for SAS/C smake 6.x to compile the AmiTCP/IP.
  474.  
  475.  
  476.  Revision Support
  477.  
  478.  
  479.     bsdsocket.library_rev.rev   Contains revision numberof the current
  480.         version (number of the latest build).  This file is updated with
  481.  
  482.         the BumpRev utility4.
  483.  
  484.     bsdsocket.library_rev.h   Automaticallygenerated by BumpRev.  Contains
  485.         build date, version and revision strings.
  486.  
  487.  
  488.  SAS/C 6.x GST Support
  489.  
  490.  
  491.     all_includes.c  C file for GST generation.  Just includes the
  492.         all_includes.h file.
  493.  
  494.     all_includes.h  Includes all header files needed by theAmiTCP/IP,
  495.         which are suitable for inclusion in a GST. Note that any headers
  496.         with inline functions can not be included in a GST.
  497.  
  498.  
  499.  Other Files
  500.  
  501.  
  502.     conf/conf.h  Static configuration information in form of preprocessor
  503.         defines.  Every C module must include this as the first include
  504.         file.
  505.  
  506.     conf/rcs.h  RCS header inclusion macro for GCC. InSAS/C this macro is
  507.         defined in the SCOPTIONS file.
  508.  
  509.     protos/*/*.h  Prototypes for functions in various modules.
  510.  
  511.  
  512.  
  513. 4.2     AmiTCP/IP Initialization
  514.  
  515.  
  516. All more or less distinct modules of theAmiTCP/IP must be initialized
  517. before they can be used for the real work.   Initialization is done in
  518. module kern/amiga_main.c, which definesfunctions init_all() and
  519. deinit_all().  The main() function calls the init_all()after it has done
  520. all needed local initializations.  If init_all() failsthe deinit_all() is
  521. called to clean up.
  522.  
  523. ________________________________
  524.    4The BumpRev is supplied by Commodore.
  525.  
  526.  
  527. 76    Section 4.2                  AmiTCP/IP                   System Manual
  528.  
  529.  
  530.  
  531. 4.2.1   init _all()
  532.  
  533. This function calls the initialization routines of all modules which have
  534. such.  This must be done carefully in the correct partial order.
  535.    There arefew general heuristics which can be applied on initialization
  536. (with respect to the ordering requirements):
  537.  
  538.  
  539.  1. Initialize the modules for which the initialization cannot fail.
  540.     This includes semaphore initializations and such.
  541.  
  542.  2. Initialize the modules which are most likely to fail, e.g.  large
  543.     memory allocations, modules which require recent versions of some
  544.     libraries etc.
  545.  
  546.  3. Initialize modules left over by rules 1 and 2.
  547.  
  548.  
  549.    Semaphoreinitializations are first, because later steps may use them
  550. to protect against race conditions.
  551.    The initialization process of the AmiTCP/IP is fully reversible.  If
  552. the initialization fails in any step thedeinit _all() function can be
  553. used to collect the garbage.
  554.    init_all() does the initializations in following order, returning
  555. nonzero if all steps succeed.  Numbers in the parenthesis are the section
  556. and page numbers for more information, respectively:
  557.  
  558.  
  559.  1. malloc_init() initializes the malloc_semaphore.  This is first since
  560.     later steps may want to use bsd_malloc() to allocatememory (5.2.2,
  561.     95).
  562.  
  563.  2. spl_init() initializes the priority level subsystem,which is used
  564.     throughout the code to protect critical sections (5.3.1, 96).
  565.  
  566.  3. sleep_init() initializes the sleep_semaphore and the sleep queues
  567.     (5.3.2, 97).
  568.  
  569.  4. readconfig() reads in and parses the command line arguments and the
  570.     configuration file.  This is the first phase which is expected to
  571.     fail.  This is done at the beginning in order to allow other
  572.     initialization functions to use the configuration information given.
  573.     Note that since the logging subsystem is not initialized yet,
  574.     readconfig() cannot log any errors encountered (4.11, 91).
  575.  
  576.  5. log_init() initializes the logging subsystem.  From now on other
  577.     initialization functions can log needed error messages (4.8, 89).
  578.  
  579.  6. mbinit() allocates memory to be used by the protocols.  This is a
  580.     candidate to fail if the memory is nearly exhausted (4.5, 79).
  581.  
  582.  7. timer_init() initializes the timeout module.  This requires version
  583.     36 or greater of the operating system.  Returns the signal mask to
  584.     wait for the timeout messages (5.1, 93).
  585.  
  586.  8. api_init() initializes and creates the master socketbase structure
  587.     (4.10.2, 91).
  588.  
  589.  9. res_init() initializes resolver structure and semaphore.
  590.  
  591.  
  592. System Manual                   AmiTCP/IP                   Section 4.3    77
  593.  
  594.  
  595.  
  596. 10. sana_init() initializes the SANA-II network interface module.   This
  597.     returns the signal mask to be used for waiting the network related
  598.     messages (4.7, 84).
  599.  
  600. 11. domaininit() initializes all configured protocols.  This is left at
  601.     the end of the initialization, since this requires the other parts of
  602.     the system to be initialized.
  603.  
  604. 12. readnetdb() initializes and reads in the network data base
  605.     information from ENV:AmInet/netdb (4.12, 92).
  606.  
  607. 13. api_show() makes the shared library interface visible on the Exec
  608.     library list (4.10.2, 91).
  609.  
  610.  
  611.  
  612. 4.2.2   deinit _all()
  613.  
  614. deinit_all() is the reverse of init_all(); it deinitializes required
  615. modules in reverse order with respect tothe initialization.
  616.    If the initialization process for a module does not allocate any
  617. resources, then there is no deinitialization function for that module.
  618. The deinitialization functions called are (in this order):
  619.  
  620.  
  621.  1. api_hide() removes the library from the Exec librarylist, so no-one
  622.     can open the library any more (4.10.2, 91).
  623.  
  624.  2. sana_deinit() deinitializes the network driver module (4.7, 84).
  625.  
  626.  3. api_deinit() deinitializes the API (4.10.2, 91).
  627.  
  628.  4. timer_deinit() deinitializes the timer module (5.1,93).
  629.  
  630.  5. mbdeinit() frees all memory used by mbufs (4.5, 79).
  631.  
  632.  6. log_deinit() deinitializes the logging subsystem (4.8, 89).
  633.  
  634.  
  635.  
  636. 4.3     The  Main  Module
  637.  
  638.  
  639. The main() function is defined in the file kern/amiga_main.c.  On startup
  640. it initializes all modules by calling init _all().  After a successful
  641. initialization it first starts the AmiTCP/IP timeouts by calling
  642. timer_send().  Then it enters the event loop.
  643.    AmigaOS function Wait() returns when one of the signals specified in
  644. the signal mask given as argument is received.   The mask currently
  645. specifies signals for SANA-II drivers, timeouts and the break signal.
  646. When some set of these signals is received the Wait() returns and its
  647. return value, which indicates the received signals, is checked.  The
  648. functions sana_poll() and timer_poll() are each called in turn if their
  649. signal was received.  They each return boolean tellingif they would like
  650. to be called again before waiting again.  The loop in which these
  651. functions are called is terminated either when no one of the poll
  652. functions wants to continue or when thebreak signal is received.
  653.    The pollfunctions do handle only one message at a time, so that any of
  654. them should not starve.
  655.  
  656.  
  657. 78    Section 4.4                  AmiTCP/IP                   System Manual
  658.  
  659.  
  660.  
  661.    When thebreak signal is received the AmiTCP/IP terminates if no
  662. library bases opened by API users are open any more.  On termination all
  663. reserved resources are freed by callingdeinit _all().
  664.  
  665.  
  666.  
  667. 4.4     Protocol Entities
  668.  
  669.  
  670. One design goal was to keep the protocolentities intact.  This is
  671. achieved through implementing all external dependencies of the protocol
  672. entities.  Fortunately the protocol entities in BSD arehighly
  673. independent of other UNIX kernel services.   For example, all dynamic
  674.  
  675. memory management is done through the memory buffer5  abstraction, which
  676. means that we only had to provide the mbuf interface and the problem of
  677. memory management was solved.
  678.    All protocol entities in a protocol family are defined in terms of a
  679. protocol switch structure.  This structure is fully defined in the header
  680. file sys/protosw.h and [Leffler et al 1991b ].  The protocol switch
  681. structure is defined as follows:
  682.  
  683.  
  684. struct protosw -
  685.     short   pr_type;             /* socket type used for */
  686.     struct  domain *pr_domain;  /* domain protocol a member of */
  687.     short   pr_protocol;         /* protocol number */
  688.     short   pr_flags;            /* protocol flags */
  689. /* protocol-protocol hooks */
  690.      void     (*pr_input)();      /* input to protocol (from below) */
  691.     int      (*pr_output)();      /* output to protocol (from above)*/
  692.      void     (*pr_ctlinput)();   /* control input (from below) */
  693.     int      (*pr_ctloutput)();   /* control output (from above) */
  694. /* user-protocol hook */
  695.     int      (*pr_usrreq)();      /* user request hook */
  696. /* utility hooks */
  697.      void     (*pr_init)();       /* initialization hook */
  698.      void     (*pr_fasttimo)();   /* fast timeout (200ms) */
  699.      void     (*pr_slowtimo)();   /* slow timeout (500ms) */
  700.      void     (*pr_drain)();      /* flush any excess space possible */
  701. ";
  702.  
  703.  
  704.    Note thatthe actual prototypes for the function pointers are omitted,
  705. see the file sys/protosw.h for full definition.
  706.    When protocol is started the pr_init() is called first to allow the
  707. protocol to initialize all needed internal structures.  Then the input
  708. process will call pr_fasttimo() and pr_slowtimo() entries periodically if
  709.  
  710. defined6.  The pr_drain() entry asks the protocol tofree all
  711. non-critical memory buffers in a low-memory situation.
  712.    Protocolscall each other through the protocol--protocol interface.  To
  713. pass a packet up in the hierarchy a protocol calls the pr_input()-entry
  714. of the protocol above it.  pr_output()-entry is called when a protocol
  715. wishes to pass a packet down in the protocol hierarchy (towards network).
  716. ________________________________
  717.    5or mbuf for short
  718.  
  719.    6Member function is defined when the value of its address is not NULL.
  720.  
  721.  
  722. System Manual                   AmiTCP/IP                   Section 4.5    79
  723.  
  724.  
  725.  
  726.    Protocolssend control information to each other through the
  727. pr_ctlinput() and pr_ctloutput() entries.
  728.    All requests coming from the API are dispatched through the pr_usrreq()
  729. entry.
  730.  
  731.  
  732.  
  733. 4.5     Memory Management
  734.  
  735.  
  736. As stated earlier, the memory managementof the protocol stack is done
  737. with memory buffers.  An mbuf is a structure containinglittle amount of
  738. storage (usually 128 bytes).  Some bytes of this storage are used for the
  739. header, but most of it is used to storeuser data.   These small buffers
  740. are linked together to get storage for larger data.
  741.    Mbufs arehighly efficient in a network protocol environment where it
  742. must be able to attach and strip protocol headers with minimum overhead
  743. and most importantly, without copying the data as doing so.  When data is
  744. stored in an mbuf chain, attaching a header is achieved by simply linking
  745. the mbuf containing the header to the head of the chain.  Removing a
  746. header is also done simply by removing the first mbuf or by incrementing
  747. the data pointer inside the mbuf.
  748.    In general there are two types of mbufs.  Ones with an packet header
  749. and ones without.  An Mbuf with packet header is used as the first mbuf
  750. of every packet.  This header contains extra information needed per
  751. packet.  See the header file sys/mbuf.h for the mbuf header definition.
  752.    Mbufs canbe chained in two dimensions.  First they may be linked to
  753. form the storage for the whole message.  Second these messages may be
  754. linked together so that the boundaries of messages are maintained.  This
  755. second feature is mainly used by messageoriented protocols such as UDP.
  756.    To gain efficiency an mbuf may have a reference to external memory page
  757. (a cluster), where a big message is copied instead of splitting it apart
  758. to many mbufs.  The main advantage of this feature is avoidance of
  759. copying the data when sending it with TCP, since the clusters are shared
  760.  
  761. between copies7.
  762.  
  763.  
  764.  
  765. 4.5.1   Mbuf  Functions
  766.  
  767.  
  768. Mbufs are accessed through set of functions which can be grouped as
  769. follows:
  770.  
  771.  
  772.  
  773. Maintenance
  774.  
  775.  
  776. int mb_check_conf(void *dp, LONG newvalue)
  777.  
  778.     Check configurable variable whose address is dp.  Return TRUE if the
  779.     newvalue is acceptable value for that variable.  See section 4.11 for
  780.     information about the configuration.
  781.  
  782.  
  783. BOOL mbinit(void)
  784. ________________________________
  785.    7TCP must keep a copy of the sent data for possible retransmissions.
  786.  
  787.  
  788. 80    Section 4.5                  AmiTCP/IP                   System Manual
  789.  
  790.  
  791.  
  792.     Initialize the whole mbuf-subsystem.  Allocate a chunk of mbufs and
  793.     clusters (using m_alloc() and m_clalloc).  Must be called before any
  794.     other mbuf-related function (except that mb_check_conf() can be
  795.     called anytime).
  796.  
  797.  
  798. void mbdeinit(void)
  799.  
  800.     Free all resources used by mbuf subsystem.  Must be called as the
  801.     last mbuf-related function in the program.
  802.  
  803.  
  804. BOOL m_alloc(int howmany, int canwait)
  805.  
  806.     Allocate howmany mbufs and place them on the mbuf free list.  If
  807.     canwait is true the caller can wait if memory is not readily
  808.     available.
  809.  
  810.  
  811. BOOL m_clalloc(int ncl, int canwait);
  812.  
  813.     Allocate ncl mbuf clusters and place them on the cluster free list.
  814.  
  815.  
  816. struct mbuf *m_retry(int i, int t)
  817.  
  818.     Ask protocols to free space when short of memory and re-attempt to
  819.     allocate an mbuf.
  820.  
  821.  
  822. void m_reclaim(void)
  823.  
  824.     Ask protocols to free space when short of memory.
  825.  
  826.  
  827.  
  828. Allocation and Deallocation
  829.  
  830. struct mbuf *m_get(int canwait, int type)
  831.  
  832.     Allocate an mbuf of type type.  If no mbufs are available we can wait
  833.     for them if canwait is M_WAIT. Initialize mbuf to contain internal
  834.     data.
  835.  
  836.  
  837. void MGET(struct mbuf *m, int canwait, int type)
  838.  
  839.     This is an macro form of above.
  840.  
  841.  
  842. struct mbuf *m_gethdr(int canwait, int type)
  843.  
  844.     Allocate an mbuf of type type.  If no mbufs are available we can wait
  845.     for them if canwait is M_WAIT. Initialize mbuf to contain a packet
  846.     header and internal data.
  847.  
  848.  
  849. void MGETHDR(struct mbuf *m, int canwait, int type)
  850.  
  851.     This is a macro form of above.
  852.  
  853.  
  854. struct mbuf *m_getclr(int canwait, int type)
  855.  
  856.     Allocate an mbuf of type type.  If no mbufs are available we can wait
  857.     for them if canwait is M_WAIT. If allocation succeeds the data buffer
  858.     is zeroed before returning.
  859.  
  860.  
  861. MCLALLOC(struct mcluster *p, int canwait)
  862.  
  863.     A macro to allocate an mbuf cluster.  The result is placed in p.
  864.  
  865.  
  866. System Manual                   AmiTCP/IP                   Section 4.5    81
  867.  
  868.  
  869.  
  870. MCLGET(struct mcluster *p, int canwait)
  871.  
  872.     A macro to add a cluster to a normal mbuf.  M_EXT flag of the mbufis
  873.     set on success.
  874.  
  875. struct mbuf *m_free(struct mbuf *m)
  876.  
  877.     Free an mbuf.  Next mbuf in the chain is returned, if any.
  878.  
  879. void MFREE(struct mbuf *m, struct mbuf *n)
  880.  
  881.     This is an macro form of above.  Successor mbuf is returned in n.
  882.  
  883. MCLFREE(struct mcluster *p)
  884.  
  885.     A macro to free an mbuf cluster.
  886.  
  887. void m_freem(struct mbuf *m)
  888.  
  889.     Free the whole chain of mbufs starting from m.
  890.  
  891.  
  892.  
  893. Utility Functions
  894.  
  895. struct mbuf *m_copym(struct mbuf *m, intoff0, int len, int canwait)
  896.  
  897.     Make a copy of an mbuf chain starting off0 bytes from the beginning
  898.     of m, continuing for len bytes.  If len is M_COPYALL, copy to endof
  899.     mbuf.
  900.  
  901. void m_copydata(struct mbuf *m, int off,int len, caddr_t cp)
  902.  
  903.     Copy data from an mbuf chain starting off bytes from the beginning,
  904.     continuing for len bytes, into buffer cp.
  905.  
  906. struct mbuf *m_prepend(struct mbuf *m, int len, int canwait)
  907.  
  908.     Prepend a chain of mbufs (m) with new mbuf with len bytes allocated
  909.     from the first mbuf aligned on a long word boundary.
  910.  
  911. void M_PREPEND(struct mbuf *m, int plen,int canwait)
  912.  
  913.     Macro version of above optimized for the most general cases.
  914.  
  915. void M_COPY_PKTHDR(struct mbuf *to, struct mbuf *from)
  916.  
  917.     Macro for copying an mbuf packet header from from to to.  from must
  918.     have flag M_PKTHDR set, and to must be empty.
  919.  
  920. void M_ALIGN(struct mbuf *m, int len)
  921.  
  922.     Macro to set the m data pointer of a newly--allocated mbuf (with
  923.     m_get()/MGET()) to place an object of the size len at the end of the
  924.     mbuf, long word aligned.
  925.  
  926. void MH_ALIGN(struct mbuf *m, int len)
  927.  
  928.     As above, but for mbufs allocated with m_gethdr()/MGETHDR() or
  929.     initialized by M_COPY_PKTHDR().
  930.  
  931. int M_LEADINGSPACE(struct mbuf *m)
  932.  
  933.     Compute the amount of space available before the current start of
  934.     data in an mbuf.
  935.  
  936.  
  937. 82    Section 4.6                  AmiTCP/IP                   System Manual
  938.  
  939.  
  940.  
  941. int M_TRAILINGSPACE(struct mbuf *m)
  942.  
  943.     Compute the amount of space available after the end of data in an
  944.     mbuf.
  945.  
  946.  
  947. void MCHTYPE(struct mbuf *m, type t)
  948.  
  949.     Change mbuf to a new type.
  950.  
  951.  
  952. void m_cat(struct mbuf *m, struct mbuf *n)
  953.  
  954.     Concatenate mbuf chain n to m.  Both chains must be of the same type.
  955.  
  956.  
  957. m_adj(struct mbuf *mp, int req_len)
  958.  
  959.     Trim req_len bytes from the head of the mbuf chain mp if req_len is
  960.     positive, else trim -- req_len bytes from the tail of the mbuf chain.
  961.  
  962.  
  963. struct mbuf *m_pullup(struct mbuf *n, int len)
  964.  
  965.     Rearrange an mbuf chain so that len bytes from the beginning of the
  966.     mbuf chain n are contiguous and in the data area of the mbuf so that
  967.     the data can be used as a structure.
  968.  
  969.  
  970.  
  971. Utility Macros
  972.  
  973. type t mtod(struct mbuf *m, type t)
  974.  
  975.     Convert mbuf pointer to a pointer to the start of the data area of
  976.     the mbuf casted to type t.
  977.  
  978.  
  979. struct mbuf *dtom(type *x)
  980.  
  981.     Convert data pointer within an mbuf to mbuf pointer.
  982.  
  983.  
  984.  
  985. 4.6     Concurrency Control
  986.  
  987.  
  988. The protocol implementation in the BSD net/2 is driven by network and
  989. timer interrupts and user processes calling the system functions.  As the
  990. whole protocol stack is moved inside normal AmigaOS process, some
  991. modifications are in place.
  992.    The processor priority levels are the main concurrency control tool of
  993. the BSD kernel.  The levels defined are SPL0 (user level), SPLSOFTCLOCK,
  994. SPLNET and SPLIMP (the most privileged level).   Execution at a higher
  995. level disables the execution at all lower levels.   InAmiTCP/IP the
  996. concurrency control is implemented either with semaphores (when
  997. debugging) or with prevention of the task switches (Forbid()/Permit()),
  998. see section 5.3.1 on page 96 for the implementation notes.
  999.    The protocol input and timeouts are driven by a single process that
  1000. manages the whole protocol stack.  The process sends appropriate IO
  1001. requests to the timer device and the SANA-II device drivers in question.
  1002. Actions are then taken as response to the returned requests.  Before any
  1003. protocol routines are called the priority level is raised either to
  1004. SPLSOFTCLOCK or SPLNET. After the function returns the priority level is
  1005. lowered back to SPL0 and the request issent back to the device driver.
  1006.  
  1007.  
  1008. System Manual                   AmiTCP/IP                   Section 4.7    83
  1009.  
  1010.  
  1011.  
  1012.    On the API side the concurrent execution of system calls is mostly
  1013. prohibited, because in UNIX the system calls are atomic in the sense that
  1014. there is never more than one system callin execution.  In AmigaOS the
  1015. shared library functions must be re-entrant so the protection must be
  1016. provided by the library functions themselves.
  1017.    The priority at which the main process runs must be above the default
  1018. value of 0 to provide enough time to process the networking protocols.
  1019. On the other side there is no sense to drive the main process at greater
  1020. priority than the SANA-II device drivers.
  1021.  
  1022.  
  1023.  
  1024. 4.7     Network  Device  Drivers
  1025.  
  1026.  
  1027. AmiTCP/IP uses standard SANA-II driversas its external network device
  1028. drivers.  A little glue is needed to attach a SANA-II driver into BSD
  1029. net/2 code.
  1030.  
  1031.  
  1032.  
  1033. Network Interface
  1034.  
  1035. The BSD net/2 networking code provides aclean interface to the network
  1036. device drivers.  The network interface provides a consistent interface
  1037. for all protocols that may be present inthe BSD Unix kernel.  Each
  1038. hardware device is associated with an unique network interface which may
  1039. be used by one or more protocol families.
  1040.    The network interface is flexible enough to attach different SANA-II
  1041. network device drivers into the AmiTCP/IP networking system.  Common
  1042. part of all network interfaces is described in [Leffler et al 1991b  ]:
  1043.  
  1044.  
  1045. struct ifnet -
  1046.          char    *if_name;               /* name, e.g. "en" or "lo" */
  1047.          short   if_unit;                /* sub-unit for lower level driver */
  1048.          short   if_mtu;                 /* maximum transmission unit */
  1049.          short   if_flags;               /* up/down, broadcast, etc. */
  1050.          short   if_timer;               /* time 'til if_watchdog called */
  1051.          int     if_metric;              /* routing metric (external only) */
  1052.          struct  ifaddr *if_addrlist;    /* linked list of addresses per if */
  1053.          struct  ifqueue -
  1054.                  struct  mbuf *ifq_head;
  1055.                  struct  mbuf *ifq_tail;
  1056.                  int      ifq_len;
  1057.                  int      ifq_maxlen;
  1058.                  int      ifq_drops;
  1059.          " if_snd;                       /* output queue */
  1060. /* procedure handles */
  1061.          int     (*if_init)();           /*init routine */
  1062.          int     (*if_output)();         /* output routine (enqueue) */
  1063.          int     (*if_start)();         /* initiate output routine */
  1064.          int     (*if_done)();           /*output complete routine */
  1065.          int     (*if_ioctl)();         /* ioctl routine */
  1066.          int     (*if_reset)();         /* bus reset routine */
  1067.          int     (*if_watchdog)();      /* timer routine */
  1068. /* generic interface statistics */
  1069.          int     if_ipackets;            /* packetsreceived on interface */
  1070.  
  1071.  
  1072. 84    Section 4.7                  AmiTCP/IP                   System Manual
  1073.  
  1074.  
  1075.  
  1076.          int     if_ierrors;             /* input errors on interface */
  1077.          int     if_opackets;            /* packetssent on interface */
  1078.          int     if_oerrors;             /* output errorson interface */
  1079.          int     if_collisions;         /* collisions on csma interfaces */
  1080. /* end statistics */
  1081.          struct  ifnet *if_next;
  1082. ";
  1083.  
  1084.  
  1085.    Network interface for SANA-II devices are handled in the module
  1086. net/if_sana.c.  This is the only module aware of SANA-II devices inside
  1087. the AmiTCP/IP network process.  It hides most SANA-II specific details
  1088. from the rest of the code.
  1089.  
  1090.  
  1091.  
  1092. Module Initialization
  1093.  
  1094. ULONG sana_init(void)
  1095.  
  1096.     This initialization routine is called at startup time before any
  1097.     interfaces have been added to system.  It creates the common message
  1098.     port used for all SANA-II network interfaces.  It also attaches the
  1099.     loopback device into system.  It returns the signal mask of the
  1100.     message port, if its creation was successful.
  1101.  
  1102. void sana_deinit(void)
  1103.  
  1104.     This routine frees all resources allocated by the SANA-II interface
  1105.     module.  It aborts all pending IO requests, frees them, closes
  1106.     network device drivers and frees the corresponding network
  1107.     interfaces.  Finally it deletes the message port.
  1108.  
  1109.  
  1110.  
  1111. 4.7.1   SANA-II Soft Network Interface
  1112.  
  1113. A message passing system based on the normal Exec IO requests is used to
  1114. transfer packets between the AmiTCP/IP and SANA-II devices.  The IO can
  1115. be either synchronous or asynchronous.  The SANA-II interface module has
  1116. a message port, which receives all fulfilled or aborted asynchronous IO
  1117. messages.  A dispatch method (currently a dispatch function pointer) have
  1118. been added to all asynchronously sent IOrequests.   Dispatching function
  1119. handles the received message in an appropriate way.
  1120.    A messagemay contain received packet, some buffers allocated for the
  1121. sent message or an event mask.  Dispatcher functions feed the received
  1122. data to the protocol input queues.  If needed, the protocol input
  1123. routines are run.  Dispatchers also free the memory allocated for the
  1124. sent packets, or relays events to the higher level protocols.
  1125.    Because the interface for the SANA-II device driver must handle many
  1126. different protocols and network adapters, it has some private data hidden
  1127. from the rest of the system.  The struct sana_softc network interface is
  1128. defined in file net/if_sana.h:
  1129.  
  1130. /*
  1131.  * SANA-II Interface descriptor
  1132.  *      NOTE: most of the code outside will believe this to be simply
  1133.  *      a "struct ifnet". The other information is, on the other hand,
  1134.  *      our own business.
  1135.  
  1136.  
  1137. System Manual                   AmiTCP/IP                   Section 4.7    85
  1138.  
  1139.  
  1140.  
  1141.  */
  1142. struct sana_softc -
  1143.   struct ifnet    ss_if;               /* network-visible interface */
  1144.   struct in_addr  ss_ipaddr;          /* copy of ip address */
  1145.   ULONG            ss_hwtype;           /* wiretype */
  1146.   UBYTE            ss_hwaddr[MAXADDRSANA]; /* Generalhardware address */
  1147.   struct Device  *ss_dev;              /* pointer todevice */
  1148.   struct Unit    *ss_unit;             /* pointer to unit */
  1149.   VOID            *ss_bufmgnt;         /* magic cookie for buffer mngement */
  1150.   UWORD            ss_reqno;            /* # of requests to allocate */
  1151.   struct IOIPReq *ss_reqs;             /* allocated requests*/
  1152.   struct MinList  ss_freereq;         /* free requests */
  1153. #if     INET
  1154.   struct -
  1155.     UWORD reqno;               /* for listening ip packets */
  1156.     UWORD sent;
  1157.     ULONG type;
  1158.   " ss_ip;
  1159.   struct -                        /* for ARP */
  1160.     UWORD reqno;
  1161.     UWORD sent;
  1162.     ULONG type;                  /* ARP packet type */
  1163.     ULONG hrd;                    /*ARP header type */
  1164.     struct arptable *table;     /* ARP/IP table */
  1165.   " ss_arp;
  1166. #endif  /* INET */
  1167.   UWORD            ss_rawreqno;        /* for raw packets */
  1168.   UWORD            ss_rawsent;
  1169.   struct sana_softc *ss_next;
  1170.   char             ss_name[IFNAMSIZ];  /* namelives here */
  1171. ";
  1172.  
  1173.    There isan external interface to this structure via SIOCSSANATAGS and
  1174. SIOCGSANATAGS ioctls.
  1175.  
  1176.  
  1177. struct ifnet *iface_find(char *name)
  1178.  
  1179.     This function initializes a network interface for given interface.
  1180.     It is called on a non-existent interface from ifunit().  It tries to
  1181.     open the appropriate SANA-II device driver, and if successful it
  1182.     initializes a descriptor and calls if_attach() with it.
  1183.  
  1184.     Its argument is the device driver name concatenated with a slash and
  1185.     unit number.  This name is used by AmiTCP/IP to open appropriate
  1186.     unit of the SANA-II driver.
  1187.  
  1188.     The initialization routine provides the specified SANA-II network
  1189.  
  1190.     device unit with the CopyToBuf() and CopyFromBuf() function tags8.
  1191.     Those tags are used to copy data to and from the internal buffers of
  1192.     the network device.  The taglist given to the device driver is
  1193.     defined in file net/sana2copybuff.c.
  1194.  
  1195.     After successful open iface_find() initializes the appropriate
  1196.     members of the new sana_softc structure.  It stores the device and
  1197.     unit pointers, magic cookie for buffer management, hardware type, MTU
  1198. ________________________________
  1199.    8For discussion for these functions, see [SANA-II 1992 add  ]
  1200.  
  1201.  
  1202. 86    Section 4.7                  AmiTCP/IP                   System Manual
  1203.  
  1204.  
  1205.  
  1206.     and address length.  It also searches for the hardware type specific
  1207.     taglist, and sets the rest of interface parameters according the
  1208.     taglist.
  1209.  
  1210.     Next the interface initialization routine attaches the new network
  1211.     interface into ifnet list with if_attach().  Then it initializes
  1212.     interface with if_init().
  1213.  
  1214.  
  1215.  
  1216. Interface Routines
  1217.  
  1218. BOOL sana_poll(void)
  1219.  
  1220.     The AmiTCP/IP processes received messages by calling this function.
  1221.     It effectively hides the actual implementation from the rest of the
  1222.     system.  This routine is called when AmiTCP/IP receives the signal
  1223.     allocated by sana_init(), and it returns TRUE, if itshould be called
  1224.     again before Wait().
  1225.  
  1226.     sana_poll() retrieves messages from the message port, dispatches them
  1227.     and then runs the input queues.
  1228.  
  1229. int sana_output(struct ifnet *ifp, struct mbuf *m0,
  1230.                 struct sockaddr *dst, struct rtentry *rt)
  1231.  
  1232.     This function is used as the if_output() method.  It tries to get a
  1233.     free IO request from the ss_freereq list.  If no free request is
  1234.     available it drops the packet.  It attaches the packet m0 to request,
  1235.     sets dispatching function to free_written_packet() and sends the
  1236.     request to the device driver.
  1237.  
  1238.     The raw packets to the SANA-II interface use the following variation
  1239.     of socket address.  The addressing family of the raw packets must be
  1240.     AF_UNSPEC. Currently only the ARP uses the raw SANA-II packets.
  1241.  
  1242.  
  1243.     /*
  1244.      * A socket address for a generic SANA-II host
  1245.      */
  1246.     struct sockaddr_sana2 -
  1247.        u_char ss2_len;
  1248.        u_char ss2_family;
  1249.        u_long ss2_type;
  1250.        u_char ss2_host[MAXADDRSANA];
  1251.     ";
  1252.  
  1253.  
  1254. void sana_ioctl(struct ifnet *ifp, int cmd, caddr_t data)
  1255.  
  1256.     This function is used as the if_ioctl() method.  SANA-II devices and
  1257.     their respective network interfaces are configured via raw sockets by
  1258.     the IoctlSocket() requests.  When the sana_ioctl() gets the
  1259.     SIOCSIFADDR request, it changes the IP address of the interface.  The
  1260.     SIOCGIFFLAGS ioctl is used to set the parameter flags of the
  1261.  
  1262.     interface9.
  1263.  
  1264.     Special SANA-II configuration is done with SIOCSSANATAGS ioctl.  It
  1265.     passes a tag list to the parse_sana_param_tags() function.
  1266. ________________________________
  1267.    9See file sys/ioctl.h for full listof all ioctls
  1268.  
  1269.  
  1270. System Manual                   AmiTCP/IP                   Section 4.7    87
  1271.  
  1272.  
  1273.  
  1274. void if_down(struct ifnet *ifp)
  1275.  
  1276.     This function pulls into if_ioctl() from net/if.h.  if_down() marks
  1277.     the interface down and informs all affected network protocols about
  1278.     the matter.  If the interface handles SANA-II device, it calls
  1279.     sana_down(), which handles the dirty work to put theinterface down.
  1280.  
  1281. static void sana_run(struct sana_softc *ssc, int n, struct ifaddr *ifa)
  1282.  
  1283.     sana_run() configures the SANA-II interface and allocates the IO
  1284.     requests to use with the SANA-II device driver.  Because the SANA-II
  1285.     device can be configured only once (see S2_CONFIGINTERFACE in
  1286.     [SANA-II 1992 add  ]) the initialization routine does not configure it.
  1287.     Among other things the hardware address of the network adapter is set
  1288.     in configuration process.  This function is called by the SIOGSIFADDR
  1289.     ioctl, which also sets the protocol address of the interface.
  1290.  
  1291. static void sana_up(struct sana_softc *ssc)
  1292.  
  1293.     sana_up() marks interface up and enables the interface to listen the
  1294.     packets from the network.  It sends read request with an appropriate
  1295.     packet type number and dispatch function to the device.
  1296.  
  1297. static BOOL sana_down(struct sana_softc*ssc)
  1298.  
  1299.     sana_down() aborts all pending requests sent to a SANA-II device
  1300.     driver.
  1301.  
  1302. static void sana_ip_read(struct sana_softc *ssc,
  1303.     struct IOIPReq *req) and
  1304.  
  1305. static void sana_arp_read(struct sana_softc *ssc,
  1306.     struct IOIPReq *req)
  1307.  
  1308.     These dispatch functions are used to feed data from a network device
  1309.     to the protocol input queues.  The network interface has not the
  1310.     input routines as members.  Dispatching functions allocate mbufs for
  1311.     the next packet and send IO requests again to the network device.
  1312.  
  1313.  
  1314.  
  1315. Statistics
  1316.  
  1317. BSD Network interface contains a lot ofexcessive statistical data.  Most
  1318. of it is made redundant by the statistics gathered by the SANA-II driver.
  1319. Because network statistics are not retrieved by looking at /dev/kmem,
  1320. there is no need to gather BSD compatible statistics.  A public ARexx
  1321. port, named AMITCP, is set up for statistics retrieval and we can use
  1322. appropriate SANA-II commands to get needed data when asked.
  1323.  
  1324.  
  1325.  
  1326. 4.7.2   ARP
  1327.  
  1328. The requirements for the ARP implementation for a SANA-II interface
  1329. differ radically from the original implementation BSD. The original code
  1330. was written exclusively for the Ethernet, which has a global addressing
  1331. scheme and a fixed address length.
  1332.    The SANA-II ARP (in the module net/sana2arp.c) holds a separate address
  1333. mapping cache for each interface.  The number of entries in the cache may
  1334.  
  1335.  
  1336. 88    Section 4.8                  AmiTCP/IP                   System Manual
  1337.  
  1338.  
  1339.  
  1340. be configured at the run time.  The hardware address length varies from
  1341. one interface to another.  The mapping caches are hashtables with linked
  1342. lists, so there is no limitations in thebucket size.  ARP Table locking
  1343. is done with a signal semaphore insteadof spln() functions.
  1344.    The ARP table is externally accessed only by IoctlSocket() calls.  With
  1345. the new SIOCGARPT ioctl the whole ARP cache may be read at once.  There
  1346. is no need to awkwardly read /dev/kmem.
  1347.  
  1348.  
  1349.  
  1350. 4.8     Logging
  1351.  
  1352.  
  1353. As everything is not predictable, programs like to inform the user about
  1354. certain situations to help the user and/or maintainer to get programs
  1355. work better.  This is the motivation for log() and panic() functions.
  1356. The fact that the file I/O routines can't be called from interrupts must
  1357. be taken into account, since a program may want to inform the user even
  1358. while executing at an interrupt level.
  1359.    Among thevery few functions of the AmigaOS which are callable from
  1360. interrupts are GetMsg() and PutMsg().  These are used to implement the
  1361. logging subsystem.
  1362.    When AmiTCP/IP has something to tell to the user, it first checks if
  1363. there is any free messages available.  There is only alimited number of
  1364. these messages to use, since they are preallocated during
  1365.  
  1366. initialization10.  If there is no message available, a counter indicating
  1367. that the message could not be deliveredis incremented.  If a free
  1368. message is available, the text given bycaller is printed into the buffer
  1369. of the message.  Then the message is sent to the private port of the
  1370. NETTRACE task.
  1371.    The NETTRACE task is created early in the initialization of the
  1372. AmiTCP/IP. This task waits for incomingmessages and when one arrives,
  1373. it prints the message to the log windowand/or log file.  Then message is
  1374. freed by sending it back to AmiTCP/IP for reuse.   If loss of log
  1375. messages is detected, log() is called totell that to the user.
  1376.    The functions are defined as follows:
  1377.  
  1378.  
  1379. int log(unsigned long level, const char*fmt, ...)
  1380.  
  1381.     This logs a message with format specified in exec.library/RawDoFmt(),
  1382.     similar to the printf().  It is preceded with ``<N>'' where N is a
  1383.     level as defined in file sys/syslog.h.
  1384.  
  1385. void panic(const char *fmt, ...)
  1386.  
  1387.     When this function is called, we are in BIG trouble.  If task, which
  1388.     called this, is not AmiTCP/IP, we just halt this task and send a
  1389.     message to AmiTCP/IP to halt immediately and free all resources.
  1390.     Format is as in exec.library/RawDoFmt().
  1391.  
  1392.     If AmiTCP/IP runs into a panic() it first patches all API functions
  1393.     to return an error code to the caller.  Then, if the panic() was not
  1394.     in the context of the AmiTCP/IP it signals the AmiTCP/IP and halts.
  1395.     As the AmiTCP/IP receives the signal, it send a message to the log
  1396. ________________________________
  1397.   10This is because memory cannotbe allocated from interrupt code.
  1398.  
  1399.  
  1400. System Manual                   AmiTCP/IP                   Section 4.9    89
  1401.  
  1402.  
  1403.  
  1404.     and signals all application programs waiting for network to take
  1405.     attention.  As this is done, it opens an User Requester to inform the
  1406.     user.  After the user responds, AmiTCP/IP waits for all library
  1407.     openers to close libraries and finally unloads itself from the
  1408.     memory.
  1409.  
  1410. int printf(const char *fmt, ...)
  1411.  
  1412.     Like the normal C--library printf (with format of
  1413.     exec.library/RawDoFmt()) except that the printing is done using the
  1414.     logging mechanism.
  1415.  
  1416. int sprintf(char *buf, const char *fmt,...)
  1417.  
  1418.     As in a normal C--library.  Format is as in exec.library/RawDoFmt().
  1419.  
  1420.  
  1421.    All functions (except panic()) return number of printed (or logged)
  1422. characters.
  1423.  
  1424.  
  1425.  
  1426. Initialization Routines
  1427.  
  1428. BOOL log_init(void)
  1429.  
  1430.     This function initializes NETTRACE subsystem by opening
  1431.     intuition.library for opening UserRequest in the case of panic().
  1432.     The the log messages are initialized to use by preallocating memory
  1433.     for them.
  1434.  
  1435.     Then NETTRACE is started and AmiTCP/IP waits for a signal from it.
  1436.     If NETTRACE success in it's initialization, then it sends a message
  1437.     back, which is then replied.  If initialization fails, a variable is
  1438.     set to specific value and CTRL-F is sent to the AmiTCP/IP. If all
  1439.     this succeeds, the log messages are initialized and sent to
  1440.     logReplyPort which works as a queue for the free messages.
  1441.  
  1442. void log_deinit(void)
  1443.  
  1444.     This works as reverse to initialization process.  If NETTRACE is
  1445.     still running, a message is sent to it telling it to terminate.  Then
  1446.     AmiTCP/IP waits until the message is replied.  Then the memory
  1447.     reserved by the messages can be freed.  Finally the intuition.library
  1448.     is closed.
  1449.  
  1450.  
  1451.  
  1452. 4.9     ARexx Interface
  1453.  
  1454.  
  1455. The ARexx port of the AmiTCP/IP is maintained by the NETTRACE task.  The
  1456. messages are parsed with parseline() (defined in kern/amiga_config.c).
  1457.  
  1458.  
  1459.  
  1460. Initialization Routines
  1461.  
  1462. ULONG rexx_init(void)
  1463.  
  1464.     This initialization routine is called at the startup time of the
  1465.     NETTRACE process.  It opens the utility.library and the
  1466.     rexxsyslib.library to be used by the ARexx code and creates a public
  1467.  
  1468.  
  1469. 90    Section 4.10                 AmiTCP/IP                  System Manual
  1470.  
  1471.  
  1472.  
  1473.     ARexx message port.  The signal mask of the ARexx port is returned
  1474.     upon a successful initialization.
  1475.  
  1476.  
  1477. void rexx_deinit(void)
  1478.  
  1479.     Free all resources allocated by the ARexx interface module.  First
  1480.     the ARexx port is removed from the system's list of message ports so
  1481.     that no-one is able find the port any more to send new messages.
  1482.     Then all pending messages are returned with error code set.  Finally
  1483.     the ARexx port is deleted and libraries opened by rexx_init() are
  1484.     closed.
  1485.  
  1486.  
  1487.  
  1488. Reply Routine
  1489.  
  1490. BOOL rexx_poll(void)
  1491.  
  1492.     Checks if any ARexx messages has arrived and handles them one at a
  1493.     time.  The parseline() function is used to parse and execute the
  1494.     given command.  Returns TRUE if there might still be messages to
  1495.     handle, otherwise the return value is FALSE.
  1496.  
  1497.  
  1498.  
  1499. 4.10     Application  Interface  Concepts
  1500.  
  1501.  
  1502. 4.10.1   SocketBase -- an Extension of the Task Structure
  1503.  
  1504. In Unix systems, where the network codeis integrated into the kernel, a
  1505. process structure holds fields for per-process information of network
  1506. related data.  In AmiTCP/IP, where socket API is implemented as a shared
  1507. library, each opener gets a newly created library base that holds data
  1508. used by the AmiTCP/IP system.  Each library base function makes sure
  1509. that the caller is from the right Amigatask and refuses to operate if
  1510. wrong task is attempting to use it (seesection 5.5 on page 100 for
  1511. detailed information).
  1512.  
  1513.  
  1514.  
  1515. 4.10.2   The System Call Semaphore and Task Priorities
  1516.  
  1517. Currently, when program enters to some of socket library functions, it
  1518. attempts to get semaphore to hold othercallers executing library code
  1519. simultaneously.  This is done so, since in Unix system,where this code
  1520. originally runs, doesn't pre-empt process that is executing system call.
  1521. In BSDSS, where ``Unix system calls'' run in user mode, system call
  1522. emulation glue uses a mutex to prevent simultaneous use of that part of
  1523. the server code.  Although spl functions are used in NET/2 code to
  1524. prevent simultaneous access of criticalsections, there may still be some
  1525. sections that leave out protection if system call semaphore is removed.
  1526. Unnecessary system call semaphore usageis going to be removed in later
  1527. releases.  Hopefully it, and the overhead it generates,becomes obsolete.
  1528.    The priority of the application process is raised to the same with the
  1529. AmiTCP/IP, while the application executes AmiTCP/IP code.  This is to
  1530. prevent situations where a process witha low priority gets blocked for a
  1531. long time while holding e.g.  the system call semaphore, since otherwise
  1532.  
  1533.  
  1534. System Manual                  AmiTCP/IP                 Section 4.11    91
  1535.  
  1536.  
  1537.  
  1538. all networking programs would be blockedwith it.   Thisapplies to all
  1539. semaphores used internally by the AmiTCP/IP, not just the system call
  1540. semaphore.
  1541.  
  1542.  
  1543.  
  1544. Initialization Routines
  1545.  
  1546. Making application interface visible andoperative contains a few steps:
  1547. call to api_init() creates the master socket library base and initializes
  1548. semaphores and lists API needs.  Library base is not inExec library base
  1549. list yet.  Routine api_show() checks first if bsdsocket.library is
  1550. already in Exec list and if not, calls Exec AddLibrary() to make it
  1551. visible.
  1552.    AmiTCP/IPcan remove socket library from the Exec list at any time,
  1553. i.e.  make it not visible, by calling api _hide().  No new socket bases
  1554. can be opened after this call.  Socket bases opened before api _hide()
  1555. operate normally.  If AmiTCP/IP calls api_show() again, new libraries can
  1556. be opened.
  1557.    api_setfunctions() takes all socket library bases out of operation.  It
  1558. sets all function vectors in every socket base to return an error.  This
  1559. function is called if AmiTCP/IP panic()ed and all libraries are expected
  1560. to be closed.
  1561.    When application interface is to be removed from system, api_deinit()
  1562. is called.  It waits for all opened libraries to closeand then calls
  1563. expunge function to deallocate the master socket base from the memory.
  1564.  
  1565.  
  1566.  
  1567. 4.11     Configuration  Variables
  1568.  
  1569.  
  1570. The configuration variable definitions are stored into a structure named
  1571. cfg_variable.  It is defined in kern/amiga_netdb.h as follows:
  1572.  
  1573.  
  1574. /* Variable types */
  1575. /* Note: Query calls value, Set calls notify functions */
  1576. enum var_type
  1577. -
  1578.  VAR_FUNC = 1,           /* value is function pointer */
  1579.  VAR_LONG,               /* value is pointer to LONG */
  1580.  VAR_STRP,               /* value is pointer to string */
  1581.  VAR_FLAG,               /* LONG value is set once */
  1582.  VAR_INET,               /* struct sockaddr_in */
  1583.  VAR_ENUM                /* value is pointer to long, whose value is set
  1584.                              according to a enumeration string in notify*/
  1585. ";
  1586.  
  1587.  
  1588. typedef LONG
  1589.   (*var_f)(struct CSource *args, UBYTE **errstrp, struct CSource *res);
  1590. typedef int (*notify_f)(void *pt, LONG new);
  1591.  
  1592.  
  1593. /* Configureable variable structure */
  1594. struct cfg_variable -
  1595.   enum var_type type;            /* type of value */
  1596.  
  1597.  
  1598. 92    Section 4.12                 AmiTCP/IP                  System Manual
  1599.  
  1600.  
  1601.  
  1602.   WORD  flags;                   /* see below */
  1603.   const UBYTE *index;            /* optional index keyword list */
  1604.   void  *value;                  /* pointer to value... */
  1605.   notify_f notify;               /* notification function */
  1606. ";
  1607.  
  1608.  
  1609. #define boolean_enum (notify_f)"NO=FALSE=OFF=0,YES=TRUE=ON=1"
  1610.  
  1611.  
  1612. /* Variable flags */
  1613. #define VF_TABLE    (1<<0) /* with an index... */
  1614. #define VF_READ     (1<<1) /* readable */
  1615. #define VF_WRITE    (1<<2) /* writeable */
  1616. #define VF_CONF     (1<<3) /* writeable only during configuration */
  1617. #define VF_RW       (VF_WRITE_VF_READ)
  1618. #define VF_RCONF    (VF_CONF_VF_READ)
  1619. #define VF_FREE     (1<<8) /* free when replaced? */
  1620.  
  1621.  
  1622.    The configuration file (by default AmiTCP:db/AmiTCP.config) is read
  1623. with the function readconfig().  This function also parses the command
  1624. line arguments.
  1625.  
  1626.  
  1627.  
  1628. 4.12     Network  Database
  1629.  
  1630.  
  1631. The network database is initialized by the init _netdb() function.  This
  1632. function allocates the NetDataBase structure and parses the file
  1633. AmiTCP:db/netdb.  The NetDataBase structure is definedas follows:
  1634.  
  1635.  
  1636. struct NetDataBase -
  1637.   struct SignalSemaphore ndb_Lock;
  1638.   struct MinList          ndb_Hosts;
  1639.   struct MinList          ndb_Networks;
  1640.   struct MinList          ndb_Services;
  1641.   struct MinList          ndb_Protocols;
  1642.   struct MinList          ndb_NameServers;
  1643.   struct MinList          ndb_Domains;
  1644. ";
  1645.  
  1646.  
  1647.    This structure contains a lock and lists for the different network
  1648. database entries.  The lock semaphore is obtained in the shared mode for
  1649. reading, and in the exclusive mode for writing.   See section 2.5.1 for
  1650. the information about the different entries.
  1651.  
  1652.  
  1653.  
  1654.  
  1655.  
  1656. Chapter 5
  1657.  
  1658.  
  1659.  
  1660. Implementation Notes
  1661.  
  1662.  
  1663.  
  1664. This chapter describes some points of the implementation of the
  1665. AmiTCP/IP. The code that is not changedfrom the BSD net/2 -release is
  1666. not reviewed.  [Leffler et al 1989 ] describes the design and
  1667. implementation of the BSD Unix, including the networking system.
  1668. [Leffler et al 1991b ] is also very helpful.
  1669.    Most of the knowledge gathered during this project is gained by reading
  1670. the source code itself.  This chapter does not try to make that totally
  1671. unnecessary.
  1672.  
  1673.  
  1674.  
  1675. 5.1     Time outs
  1676.  
  1677.  
  1678. The Unix timeout() function implements the time out needs of the Unix
  1679. kernel.  When kernel code calls timeout(), the functiongiven as argument
  1680. will be called after the specified timeout has elapsed.  In AmigaOS time
  1681. outs are provided by the timer device.  AmiTCP/IP sendstime out
  1682. requests to the device and gets them back when the time specified has
  1683. elapsed.
  1684.    The functions called by the time out service are:
  1685.  
  1686.  
  1687. if_slowtimo()
  1688.  
  1689.     This is the time out function of the network interfaces and is
  1690.     defined in net/if.c.
  1691.  
  1692.  
  1693. arptimer()
  1694.  
  1695.     Handles the time outs of ARP protocol (net/sana2arp.c).
  1696.  
  1697.  
  1698. pfslowtimo()
  1699.  
  1700.     This is the main slow time out function for all protocols.  It calls
  1701.     the pr_slowtimo() function of each configured protocol.   The interval
  1702.     of this timer is 500 ms (kern/uipc_domain.c).
  1703.  
  1704.  
  1705. pffasttimo()
  1706.  
  1707.     Is the corresponding function for fast (200 ms) time outs.
  1708.  
  1709.  
  1710.  
  1711.                                       93
  1712.  
  1713.  
  1714. 94    Section 5.1                  AmiTCP/IP                   System Manual
  1715.  
  1716.  
  1717.  
  1718.    The request structure used by AmiTCP/IP has few fields in addition to
  1719.  
  1720. the normal struct timerequest1.  The structure is defined in
  1721. kern/amiga_time.h as follows:
  1722.  
  1723. struct timeoutRequest -
  1724.   struct timerequest timeout_request;   /* timer.device sees only this */
  1725.   struct timeval     timeout_timeval;   /* timeout interval */
  1726.   TimerCallback_t    timeout_function;  /* timeout function to be called */
  1727. ";
  1728.  
  1729.  
  1730.    In this implementation the time out functions themselves do not call
  1731. any time out services, but the functionsare called by timer_poll(),
  1732. which is called by main() when there might be a message to handle (e.g.
  1733. when the timer signal is received).  timer_poll() checks the reply port
  1734. to see if there really is a message to handle.   Afterthe time out
  1735. function is serviced timer_poll() sends the request back to the timer
  1736. device and returns.
  1737.    Time outservice is implemented by files kern/amiga_time.c and
  1738. kern/amiga_time.h.  The functions defined are:
  1739.  
  1740.  
  1741. ULONG timer_init(void)
  1742.  
  1743.     Initializes the time out subsystem by allocating the IO requests and
  1744.     opening the timer device.  Note that AmiTCP/IP uses functions that
  1745.     are new to version 36 of the timer device, so the code refuses to
  1746.     success with Kickstart 1.3 (or lower).
  1747.  
  1748.     Returns the signal mask to wait for if successful.
  1749.  
  1750. void timer_deinit(void)
  1751.  
  1752.     Frees all resources used by time out subsystem.
  1753.  
  1754. void timer_send(void)
  1755.  
  1756.     Sends time out requests allocated by timer_init() tothe timer
  1757.     device.
  1758.  
  1759. struct timeoutRequest *createTimeoutRequest(TimerCallback_t fun,
  1760.     ULONG seconds, ULONG micros)
  1761.  
  1762.     Creates a new time out request.  This can be called only after
  1763.     successful timer_init().
  1764.  
  1765. void deleteTimeoutRequest(struct timeoutRequest *tr)
  1766.  
  1767.     Deletes requests created by createTimeoutRequest().
  1768.  
  1769. BOOL timer_poll(VOID)
  1770.  
  1771.     Checks if there are any timer requests in the reply port and if there
  1772.     is handles them by calling the handleTimeoutRequest().  Then it sends
  1773.     the request back to the timer device.
  1774.  
  1775. void handleTimeoutRequest(struct timeoutRequest *tr)
  1776.  
  1777.     Inline function which simply calls the function specified in the time
  1778.     out request.
  1779. ________________________________
  1780.    1See standard Amiga include file devices/timer.h
  1781.  
  1782.  
  1783. System Manual                   AmiTCP/IP                   Section 5.2    95
  1784.  
  1785.  
  1786.  
  1787. void sendTimeoutRequest(struct timeoutRequest *tr)
  1788.  
  1789.     Inline function which sends the request to the timer device.
  1790.  
  1791.  
  1792.    See the files kern/amiga_main.c and kern/amiga_time.c for example of
  1793. the usage.
  1794.  
  1795.  
  1796.  
  1797. 5.2     Memory Management
  1798.  
  1799.  
  1800. 5.2.1   Mbufs
  1801.  
  1802. Mbufs are ported just as they are.  Memory is allocatedin small chunks
  1803. for both mbufs and clusters.  The size of the cluster and the number of
  1804. mbufs to allocate in one chunk are configurable variables, see section
  1805. 2.4 for summary of the configurable variables in general.
  1806.    Note thatsince data must be copied at the SANA-II interface there is
  1807. no need to use trailer protocols (whosemain gain is avoidance of that
  1808.  
  1809. copy) and so the mbuf clusters need notbegin at page boundaries2.   This
  1810. fact lead to the implementation of the clusters where the size of the
  1811. cluster may be arbitrary (now user configurable) and the reference count
  1812. of the cluster is stored in a little header before the actual data.
  1813.    One noteon allocating memory for the mbufs:  Since the mbuf must be
  1814. perfectly aligned (i.e.  128 byte mbuf must be 128--aligned), we need to
  1815. allocate one extra mbuf to be able to align the mbufs in arbitrary memory
  1816. chunk returned by Exec AllocMem().
  1817.    The 'canwait' argument of the mbuf functions is ignored by now, more
  1818. memory will be allocated if limit of maximum memory usage is not hit.
  1819. This is all right as long as the mbuf allocation functions are not called
  1820. from interrupts.  The only functions in the AmiTCP/IP which may get
  1821. called from the interrupt code are the SANA-II callback functions
  1822. m_copy_from_mbuf() and m_copy_to_mbuf()defined in file
  1823. net/sana2copybuff.c.
  1824.    The function descriptions for the mbufs are on section 4.5.  See files
  1825. sys/mbuf.h and kern/uipc_mbuf.c for the actual implementation.
  1826.  
  1827.  
  1828.  
  1829. 5.2.2   malloc() & free()
  1830.  
  1831. Do not call the malloc() and free() functions directly!  Since AmiTCP/IP
  1832. is multi--threaded program these functions are not safe, since they use
  1833. static data.  File sys/malloc.h defines two inline functions to be used
  1834. instead.  They are defined as follows:
  1835.  
  1836.  
  1837. static inline void * bsd_malloc(unsignedlong size, int type, int flags)
  1838.  
  1839.     This function calls malloc() to allocate memory of size size and type
  1840.     type.  The types are defined in sys/malloc.h and are used for
  1841.     bookkeeping purposes.  The flags may have either value M_WAITOK or
  1842.     M_NOWAIT. The flags are not used by this implementation, however, but
  1843.     are defined for portability.
  1844. ________________________________
  1845.    2Well, there is no virtual memory in Amiga either.
  1846.  
  1847.  
  1848. 96    Section 5.3                  AmiTCP/IP                   System Manual
  1849.  
  1850.  
  1851.  
  1852. static inline void bsd_free(void *addr,int type)
  1853.  
  1854.     Frees memory allocated by bsd_malloc().
  1855.  
  1856.  
  1857.    The malloc() and free() are made safe by malloc_semaphore, which
  1858. protects mallocs and frees from collisions.   It is obtained before the
  1859. actual calls to malloc() or free() and released after them.
  1860.    In addition to these functions sys/malloc.h defines macro versions for
  1861. the most usual usages.
  1862.    Initialization for these functions is done by:
  1863.  
  1864.  
  1865. BOOL malloc_init(void)
  1866.  
  1867.     Initializes the malloc_semaphore.  This must be called early in the
  1868.     initialization process, since bsd_malloc() nor bsd_free() cannot be
  1869.     called before malloc_semaphore is initialized.
  1870.  
  1871.  
  1872.  
  1873. 5.3     Concurrency Control
  1874.  
  1875.  
  1876. 5.3.1   Processor Priority Levels
  1877.  
  1878. In Unix systems the critical sections are mainly protected by raising the
  1879. processor priority level (i.e.  preventing interrupts upto a certain
  1880. level).  This crude way might hurt a real time operating system as the
  1881. AmigaOS, so it can not be implemented assuch.   Besides, the AmiTCP/IP
  1882. runs as a normal user level process which has no needed privilege to
  1883. alter the interrupt levels of the processor.
  1884.    The implementation in AmiTCP/IP is twofold; a semaphore is used in the
  1885. debugging mode and task switch prevention is used in the production
  1886. version.  Using semaphore makes debugging easy as single stepping and
  1887. tracing is possible while keeping the system alive.   The semaphore adds
  1888. certain overhead which is not acceptablein the production version, so
  1889. the prevention of the task switches is used.
  1890.    When thepreprocessor symbol DEBUG is defined the spl_semaphore is
  1891. used.  When this semaphore is free the process is at level SPL0 (user
  1892. level) and when the semaphore is allocated the process is at
  1893. ``interrupt'' level (SPLSOFTCLOCK, SPLNET or SPLIMP), effectively
  1894. disallowing anyone else to enter critical section.   When the symbol DEBUG
  1895. is not defined the functions and macrosare defined differently.  They
  1896. manipulate directly the Task Disable Nest Count (TDNextCnt field of the
  1897. SysBase).  This field is normally used by Exec functions Forbid() and
  1898. Permit() which increment and decrement the value of the field,
  1899. respectively.  Since an assembler macro is provided byCommodore for the
  1900.  
  1901. Forbid() function, the semantics of thefield cannot change in the future3.
  1902. The semantics of the TDNestCnt is littleabused by the AmiTCP/IP, however.
  1903. The value of the spl level in question is directly assigned as the value of
  1904. the field.  This is not visible outside of the AmiTCP/IP, since basically
  1905. functions which use this field either directly or indirectly (via Forbid()/Perm*
  1906.  *it())
  1907. need to return the value of the field asit was when the function was called.
  1908. This is also the semantics of the usageof the spl functions.
  1909. ________________________________
  1910.    3If it would, then all the codeusing that official macro would break.
  1911.  
  1912.  
  1913. System Manual                   AmiTCP/IP                   Section 5.3    97
  1914.  
  1915.  
  1916.  
  1917.    The spl_semaphore is initialized by the function BOOL spl_init(void)
  1918. which is called among the very first functions in the initialization
  1919. process.
  1920.    The function spl _n(int) (defined in sys/synch.h) is used to alter the
  1921. priority levels.  In the non-debugging mode there are two other
  1922. functions, too:  spl_const(), which isused with a constant (non-zero)
  1923. argument, and spl_0() which is used to switch to the level 0.  In
  1924. addition, a macro has been defined for each separate level for
  1925. portability.  The macros are as follows:
  1926.  
  1927.  
  1928. spl0() switches to the normal execution level.
  1929.  
  1930.  
  1931. splsoftclock()  is the level on which timer eventsare executed.
  1932.  
  1933.  
  1934. splnet() is the level of the network interrupts in UNIX.
  1935.  
  1936.  
  1937. splimp() is the highest of the priority levels used in the networking
  1938.     code.  For example, mbuf functions are executed at this level.
  1939.  
  1940.  
  1941.    These macros return the previous level which may then be set back with
  1942. splx(int)-macro, which sets the level tothe level given as argument.
  1943.  
  1944.  
  1945.  
  1946. 5.3.2   Sleeping Facilities
  1947.  
  1948.  
  1949. Sleeping facility is implemented by kern/kern _synch.c.  Processes sleep
  1950. on a channel, which is the key used to identify sleepers.  Usually this
  1951. is some address which is unique to the calling process.  Socket base
  1952. structure for the sleeping task is linked in the sleep queue before the
  1953. actual sleep is started.  This is how the waking task can find the
  1954. sleeper to wake up when something happens on the channel the process is
  1955. sleeping on.
  1956.    The sleepqueue is implemented as a hash table, where the channel value
  1957.  
  1958. is mapped to an index of a sleep queue with the hash function4
  1959. SLEEP_HASH() (defined in kern/kern_synch.c).
  1960.    The actual sleep is implemented by sending a time out request for the
  1961. time out duration to the timer device.  The sleep completes on the time
  1962. out, a wakeup, a break signal or users specified signal.
  1963.    Note thatall critical resources (e.g.  semaphores) must be freed
  1964. before sleeping, since otherwise the whole networking code hangs.
  1965. tsleep() does this for you.
  1966.    The functions which implement the sleep system are:
  1967.  
  1968.  
  1969. BOOL sleep_init(void)
  1970.  
  1971.     This initializes the sleep_semaphore and the sleep queues.   Thismust
  1972.     be called before any other functions of this module.
  1973.  
  1974.  
  1975. int tsleep(struct SocketBase *p, caddr_tchan,
  1976.     char *wmesg, const struct timeval *time_out)
  1977. ________________________________
  1978.    4Actually a macro.
  1979.  
  1980.  
  1981. 98    Section 5.3                  AmiTCP/IP                   System Manual
  1982.  
  1983.  
  1984.  
  1985.     This function is the function usually called by the processes5 and
  1986.     implements the sleep by using the other functions of this module.
  1987.     The caller goes to sleep for at most the time specified in the struct
  1988.     timeval argument.  chan is the channel to sleep on.  wmesg is a
  1989.     string which is marked in the socket base (p) as the reason to sleep.
  1990.     Currently no-one ever reads it, though.
  1991.  
  1992.  
  1993. void wakeup(caddr_t chan)
  1994.  
  1995.     Wakes up any sleepers on channel chan.  Searches the sleep queue for
  1996.     entries with key chan and wakes them up by first clearing the key
  1997.     (p_wchan field of the socket base structure) and then signalling the
  1998.     process with the signal of the time out message.  The usage of the
  1999.     sleep queues and the p_ fields in the socket base structures are
  2000.     protected with sleep_semaphore, which must be obtained before even
  2001.     reading the sleep queues.
  2002.  
  2003.     Note that since a task in AmigaOS may get signals anytime, the
  2004.     sleeper checks the p_wchan field on reception of thesignal and if it
  2005.     is nonzero it goes to sleep again.
  2006.  
  2007.  
  2008. void tsleep_send_timeout(struct SocketBase *p,
  2009.     const struct timeval *time_out)
  2010.  
  2011.     First ensures that the message previously sent to the timer device is
  2012.     back.  Then sends timer device a time out request for duration
  2013.     specified in time_out if it is not NULL. The requestsent is
  2014.     allocated when the library is opened.
  2015.  
  2016.  
  2017. void tsleep_abort_timeout(struct SocketBase *p,
  2018.     const struct timeval *time_out)
  2019.  
  2020.     Aborts the time out sent by the tsleep_send_timeout().  This function
  2021.     must be used when the time out must be cancelled (when the sleeper is
  2022.     waken up).
  2023.  
  2024.     This function just sets the timer reply port (timerPort field of the
  2025.     socket base) to the mode in which reception of the message does not
  2026.     cause any action.
  2027.  
  2028.  
  2029. void tsleep_enter(struct SocketBase *p,caddr_t chan, char *wmesg)
  2030.  
  2031.     Puts the caller on to a sleep queue.
  2032.  
  2033.  
  2034. int tsleep_main(struct SocketBase *p, ULONG wakemask)
  2035.  
  2036.     Waits for either time out, wakeup, break or user defined action to
  2037.     happen.  The sigIntrMask field of the socket base structure defines
  2038.     which signals will cause a break.  Return value of EINTR is returned
  2039.     if any of the signals specified in that mask are received.  In
  2040.     addition the signals are set back with SetSignal() for the user
  2041.     program to be able to detect them.  The wakemask argument specifies a
  2042.     mask for signals which should cause a return from the sleep.  In such
  2043.     case the return value ERESTART is returned.
  2044. ________________________________
  2045.    5Only WaitSelect() system calluses sleeping facilities without this
  2046.  
  2047. function.
  2048.  
  2049.  
  2050. System Manual                   AmiTCP/IP                   Section 5.4    99
  2051.  
  2052.  
  2053.  
  2054.     On exit the process is guaranteed not to be in the sleep queues any
  2055.     more, but the time out remains active if it is not the reason for
  2056.     return.  Return value on wakeup is 0 and on time out EWOULDBLOCK is
  2057.     returned.
  2058.  
  2059.  
  2060.  
  2061. 5.4     Socket  Library  Creation  Procedure
  2062.  
  2063.  
  2064. Since a new socket base is created eachtime a different task opens the
  2065. AmiTCP/IP socket library, the procedureis a bit more complicated than
  2066. on libraries where the same library baseis returned (See
  2067. [RKM Libraries 1992 ]).  There is, for example, two socket library bases
  2068. in use.  All code discussed here is located in api/amiga _api.c.
  2069.  
  2070.  
  2071.  
  2072. 5.4.1   Master Library Base
  2073.  
  2074. This is the library base that is made shown by api_show() (see section
  2075. 4.10.2).  It is placed in Exec's librarylist.  This is of type struct
  2076. Library and contains information that anoutsider can read by scanning
  2077. through the Exec library list.  Information available is version and
  2078. revision numbers and count of tasks thathave (application) library base
  2079. open.
  2080.    Master library base has only functions ELL_Open() and ELL_Expunge().
  2081. When applications opens the socket library, the Exec calls ELL_Open().
  2082. This function creates new application socket bases and increments the
  2083. reference count of open application library bases.   Ifthe calling task
  2084. has a socket base open already, a new socket base is not created but the
  2085. reference count of task's socket base isincremented and the base pointer
  2086. is returned to the caller.  This feature has many useful possibilities,
  2087. for example in intermediate libraries which need to manipulate the
  2088. sockets of the calling task.
  2089.    ELL_Expunge() does (not) do one task.  When it is called, it checks if
  2090. there is any libraries still open or ifAmiTCP/IP lets this function
  2091. execute further (in fact, currently thissecond check is sufficient since
  2092. only AmiTCP/IP can close the library andit doesn't do it until all
  2093. bases has been closed.  The next Remove() is there forfuture reference
  2094. too).  Then, the memory of the master library base is deallocated and
  2095. NULL is returned (no AmigaDOS seglist tofree).   The SIGBREAKF _CTRL_C
  2096. signal that is sent with the global varianble SB _Expunged set to TRUE
  2097. notifies api_deinit() function about the fact that now all libraries are
  2098. closed.
  2099.  
  2100.  
  2101.  
  2102. 5.4.2   Application Library Bases
  2103.  
  2104. These are the library bases that are returned to the openers of the
  2105. socket library.  In this base the Open() function is obsolete since all
  2106. OpenLibrary() calls go through the master socket base.  Exec and
  2107. AmiTCP/IP generated Expunge() calls go also through the master socket
  2108. base.
  2109.    UL_Close() is the close function for all application library bases.
  2110. First it decrements the reference countof this base and returns NULL if
  2111.  
  2112.  
  2113. 100    Section 5.5                 AmiTCP/IP                  System Manual
  2114.  
  2115.  
  2116.  
  2117. there are still references left (again,NULL informs Exec that there is
  2118. no AmigaDOS seglist needed to be removed).
  2119.    If thereare no more references to this library base, following steps
  2120. are taken to remove it from the memory:  All socket descriptors still
  2121. open are closed.  The base is removed from the AmiTCP/IP list of open
  2122. application socket bases.  The timer request is deallocated.  Then the
  2123. library base is removed from the memoryand open count of application
  2124. socket bases is decremented in the master library base.  Finally,
  2125. ELL_Expunge() is called if the open count reached zero and the LIBF_DELEXP
  2126. flag is set (by a previous ELL_Expunge() call).
  2127.  
  2128.  
  2129.  
  2130. 5.5     The  SocketBase  Structure
  2131.  
  2132.  
  2133. The SocketBase structure is defined in file api/amiga_api.h as follows:
  2134.  
  2135.  
  2136. struct SocketBase -
  2137.   struct Library         libNode;
  2138. /* "Global" Errno */
  2139.   WORD                   errnoSize;
  2140. /* -- now we are longword aligned -- */
  2141.   UBYTE *                errnoPtr; /* this points to errno */
  2142.   LONG                   defErrno;
  2143. /* Task pointer of owner task */
  2144.   struct Task *          thisTask;
  2145. /* task priority changes (WORDS so we keep structure longword aligned) */
  2146.   WORD                   myPri;       /* task's priority just after libcall */
  2147.   WORD                   libCallPri; /* task's priority during library call */
  2148. /* -- descriptor sets -- */
  2149.   WORD                   dTableSize;
  2150.   WORD                   nextDToSearch;
  2151.   struct socket **      dTable;
  2152. /* AmiTCP signal masks */
  2153.   ULONG                  sigIntrMask;
  2154.   ULONG                  sigIOMask;
  2155.   ULONG                  sigUrgMask;
  2156. /* -- these are used by tsleep()/wakeup() -- */
  2157.   char *                 p_wmesg;
  2158.   queue_chain_t          p_sleep_link;
  2159.   caddr_t                p_wchan;         /* event processis awaiting */
  2160.   struct timerequest *  tsleep_timer;
  2161.   struct MsgPort *      timerPort;
  2162. /* -- pointer to select buffer during Select() -- */
  2163.   struct newselbuf *    p_sb;
  2164. /* -- per process fields used by various'library' functions -- */
  2165. /* buffer for inet_ntoa */
  2166.   char inet_ntoa[20]; /* xxx.xxx.xxx.xxx"0 */
  2167. /* pointers for data buffers that MAY beused */
  2168.   struct DataBuffer  selitems;
  2169.   struct DataBuffer  hostents;
  2170.   struct DataBuffer  netents;
  2171.   struct DataBuffer  protoents;
  2172.   struct DataBuffer servents;
  2173. ";
  2174.  
  2175.  
  2176. System Manual                  AmiTCP/IP                 Section 5.6    101
  2177.  
  2178.  
  2179.  
  2180.    libNode is a normal library base structure and is used by the system.
  2181. Since in this implementation each openergets a task specific library
  2182. base, AmiTCP/IP links all ``user librarybases'' together using Node
  2183. field of libNode.
  2184.    When socket library function encounters an error, it saves the value of
  2185. the error to the memory location addressed by errnoPtr.  errnoSize
  2186. specifies the size of the variable pointed by the errnoPtr.  By default
  2187. errnoPtr points to the defErrno but canbe changed to point any memory
  2188. location -- usually to the global errnovariable in the context of the
  2189. user task.
  2190.    In entryof each bsdsocket.library function call, value of thisTask is
  2191. compared to the task pointer of callingtask to make sure right task is
  2192. calling the function.  This variable is also used to find library base of
  2193. some executing task.
  2194.    When taskis executing system calls in bsdsocket.library, its process
  2195. priority is changed to the same as thatof the AmiTCP/IP task in order
  2196. not to hold semaphores and block the whole network system.  If some
  2197. higher priority process becomes active and a lower priority task is
  2198. holding some vital semaphore of the AmiTCP/IP then the precess cannot
  2199. continue to run.  The manipulation of the process priorities uses myPri
  2200. and libCallPri fields of the socket base.
  2201.    dTableSize is the number of current maximum limit of socket
  2202. descriptors.  dTable is the descriptor table containingpointers to
  2203. socket structures, i.e.  sockets.  nextDToSearch makes searching of free
  2204.  
  2205. socket descriptor faster6.
  2206.    sigIntrMask is a task specific mask of the signals which should break
  2207. the Wait() call in the tsleep_main().  Reception of such signals causes
  2208. the system calls to return -1 and the error code pointed by errnoPtr to
  2209. be set to EINTR. sigIOMask field specifies the signals to send when
  2210. asynchronous notification is requested.  Signals specified in sigUrgMask
  2211. are sent when out of band data is received.   These masks implement the
  2212. functionality of the SIGIO and SIGURG signals of the Unix systems,
  2213. respectively.  All these masks can be set with the SetSocketSignals() API
  2214. call.  The default mask for the sigIntrMask specifies the signal for the
  2215. ctrl-C, other two are zero by default.
  2216.    The nextgroup of variables are used by tsleep() and wakeup().  p_wmesg
  2217. points to a string telling the reason why task is sleeping.  p _sleep_link
  2218. is used to chain library bases in the sleep queues.   Waiting channel key
  2219. is hold in variable p_wchan and data handling time outs in variables
  2220. tsleep_timer and timerPort (more about this in section 5.3.2 on page 97).
  2221.    WaitSelect() inserts one selitem on each socket it wants event
  2222. information of.  p_sb points to a newselbuf that contains these items.
  2223.    Some APIfunctions in the original environment use static buffers to
  2224. store their output.  As a shared library cannot use static buffers (to be
  2225. re-entrant), the buffers must be allocated dynamically.  The SocketBase
  2226. structure has space for the output buffer for the Inet_Ntoa() and
  2227. pointers for other needed buffers.  These buffers are allocated only when
  2228. needed.
  2229. ________________________________
  2230.    6Semantics of allocating lowestfree socket descriptor is preserved.
  2231.  
  2232.  
  2233. 102    Section 5.6                 AmiTCP/IP                  System Manual
  2234.  
  2235.  
  2236.  
  2237. 5.6     The  Application  Program  Interface
  2238.  
  2239.  
  2240.  
  2241. Most of API code is original NET/2 codetaken from BSDSS7. BSDSS mutexes
  2242. are replaced by Amiga semaphores and struct proc references are changed
  2243.  
  2244. to references to our socket library base8.
  2245.    Many functions used copyin() and copyout() to copy data around.  Those
  2246. functions copy data between system and user space (different virtual
  2247. memory mappings) in original BSD Unix system.   It is also possible that
  2248. those functions will fail e.g.  if user tries to reference illegal memory
  2249. locations.  In AmiTCP/IP system copyin() and copyout()functions are
  2250. replaced with bcopy(), arguments are thesame but the bcopy() never
  2251. fails.  Therefore some obsolete checks are removed fromthe code.
  2252.  
  2253.  
  2254.  
  2255. 5.6.1   HowAPI Functions Are Ported
  2256.  
  2257.  
  2258. Most functions in our API are ported from BSD Unix system calls.  BSD
  2259. Unix system call interface calls the actual function with three
  2260. arguments.  First is user process structure pointer.  Second contains the
  2261. given arguments and is locally named asuap structure.  Third argument is
  2262. a pointer to the return value.  The function returns error value or 0 if
  2263. no error occurred.
  2264.    The socket() function is a good example of this:
  2265.  
  2266.  
  2267.  
  2268. socket(p, uap, retval)
  2269.          struct proc *p;
  2270.          registerstruct args -
  2271.                  int      domain;
  2272.                  int      type;
  2273.                  int      protocol;
  2274.          " *uap;
  2275.          int *retval;
  2276.  
  2277.  
  2278.    The system function interface maps directly to Amiga shared library.
  2279. Since every task has socket library baseof its own, Unix process pointer
  2280.  
  2281. matches to library base pointer given inregister A69 .  uap argumentsare
  2282. passed in registers normally.  Return value is returnedin the register
  2283. D0 (as any standard C compiler does).  So the *retval was changed to a
  2284. local variable retval and removed, whennot needed.   The returned value
  2285. is -1 on error, in which case the errnois also set to indicate the error
  2286. (see file sys/errno.h for list of errorcodes), or retval, or 0 if no
  2287. other return value is needed.
  2288.    To emulate Unix system call interface, each function first obtains the
  2289. syscall_semaphore (why,see section 4.10.2 on page 90) and while this
  2290. task is holding the semaphore, no othertask can continue to execute the
  2291. ________________________________
  2292.    7BSDSS networking code is almost completely the same.
  2293.  
  2294.    8See 5.5.
  2295.  
  2296.    9All Amiga shared libraries expect them to be called relative to
  2297.  
  2298. register A6
  2299.  
  2300.  
  2301. System Manual                  AmiTCP/IP                 Section 5.7    103
  2302.  
  2303.  
  2304.  
  2305. library code10.  This means that every system call function needs to
  2306. release syscall_semaphore before returning.  To accomplish this, each
  2307. return inside the function is changed togoto Return; and at label
  2308.  
  2309. Return:  is code that releases the syscall_semaphore11 .
  2310.    The default modifications were:  changing file descriptor tables and
  2311. pointers to socket tables and pointers,respectively, removing usage of
  2312. struct fileops function pointers -- replacing them with direct socket
  2313. functions, changing copyin() and copyout() functions to bcopy()s -- no
  2314. more error checking here needed, and last, changing parameters on
  2315. tsleep() calls.
  2316.  
  2317.  
  2318.  
  2319. 5.6.2   APIFunctions Which Needed More Modifications
  2320.  
  2321. IoctlSocket()  (Former ioctl()):  Non-socket stuff removed, and ioctl code
  2322.     from soo_ioctl() inserted.
  2323.  
  2324. WaitSelect()  (Former select()) usedto count remaining time out time if
  2325.     tsleep() returned accidentally too early.  AmiTCP/IP uses the timer
  2326.     device for its time outs and the time out request is aborted only
  2327.     when it is needed again, so there is no need to send new time out
  2328.     requests (and to calculate their time out durations).  tsleep() is
  2329.     broken apart into pieces so that the time out request is sent only
  2330.     once.
  2331.  
  2332. CloseSocket()  Decreases socket's referencecount and calls soclose() to
  2333.     kill the socket if it becomes zero.
  2334.  
  2335. socket() and accept()  Added initialization of so_refcnt.  fdAlloc()
  2336.     doesn't bind fd to socket.  It is done explicitly.
  2337.  
  2338. Resolver functions  used to allocate huge amounts of stack.  Now memory is
  2339.     allocated dynamically from the head using bsd_malloc.
  2340.  
  2341.  
  2342.  
  2343. 5.7     Changes  in  Functions  Below  API  Level
  2344.  
  2345.  
  2346. Functions that API functions call are mostly functions that use struct
  2347. socket type arguments, possibly having some other arguments too.  In most
  2348. cases no modifications were needed.  There was some modifications, like
  2349. parameters for tsleep() call, which hadto be changed throughout the
  2350. code.
  2351.  
  2352.  
  2353.  
  2354. 5.7.1   Other  Changes
  2355.  
  2356. selscan()  calls soo _select() directly, and uses socket pointer instead of
  2357.     file pointer.
  2358.  
  2359. soo_select() also uses socket pointer instead of file pointer.
  2360. ________________________________
  2361.   10Not all functions require obtaining syscall_semaphore so those can continue
  2362. to run.
  2363.   11syscall_semaphore is also freed when library function does tsleep().
  2364.  
  2365.  
  2366. 104    Section 5.8                 AmiTCP/IP                  System Manual
  2367.  
  2368.  
  2369.  
  2370. socreate()  allows allsockets to be privileged.  This means that user can
  2371.     obtain raw sockets and use normally privileged port numbers.
  2372.  
  2373. sosend() uses uioread() instead of the original uiomove().  sblock() and
  2374.     sbwait() are called with library base pointer as the second argument.
  2375.  
  2376. soreceive()  uses uiowrite() instead of the original uiomove().  See above
  2377.     about the modification of call sblock() and sbwait().
  2378.  
  2379. sorflush()  calls sblock() with base pointer argument as NULL.
  2380.  
  2381. sosetopt() and sogetopt()   :  type of so_linger and so_timeo fields in
  2382.     socket structure is changed from short int to struct timeval.
  2383.     Manipulation of these data is changed accordingly.
  2384.  
  2385. sbwait() takes socket base pointer as second argument.  It is then passed
  2386.     to tsleep() (see section 5.3.2 on page 97).
  2387.  
  2388. sblock() and sb_lock():  sblock() is a macro that calls sb_lock().  Both
  2389.     take socket base pointer as second argument.  sblock() forwards that
  2390.     pointer directly to sb_lock() which, again, passes it to the
  2391.     tsleep().
  2392.  
  2393.  
  2394.  
  2395. 5.8     Agnet.device
  2396.  
  2397.  
  2398. We used the agnet.device, an SANA-II test device, to test and develop the
  2399. AmiTCP/IP network code.  The usage and features of theagnet.device are
  2400. described in the section 1.7.1, page 10.
  2401.    SANA-II is an standard network device driver interface for the Amiga
  2402. (see [SANA-II 1992 add ]).  It is an extension to the normal device
  2403. interface, which is described in the [RKM Libs & Devs 1989 ].  Device
  2404. drivers are accessed by their name fromthe system list.  Drivers may be
  2405. loaded dynamically from the disk, if they are not currently in the main
  2406. memory.  There may be several units sharing common driver code so each
  2407. (network) device is specified by an unitnumber and the device driver
  2408. name.
  2409.    We wrotethe agnet.device using the SLIP driver which Commodore has
  2410. provided as the example code for SANA-IIdrivers.   However, there was
  2411. some problems with the supplied code.  First, the SLIPdriver code
  2412. obviously follows an obsolete SANA-II draft.   There was some
  2413. modifications in the final standard e.g.  in the eventhandling and
  2414. multicast addressing.
  2415.    The provided example code was also very fragile, it did not get
  2416. compiled as such with the newer SAS C version 6.   Codedepended on some
  2417. features of the SAS C 5.10.  For example, it always expected to find
  2418. device base pointer in address registerA6.
  2419.  
  2420.  
  2421.  
  2422. 5.8.1   IO Commands
  2423.  
  2424. There is a detailed description of SANA-II device commands and functions
  2425. in [SANA-II 1992 add ].  The following IO commands are implemented in
  2426. agnet.device:
  2427.  
  2428.  
  2429. System Manual                  AmiTCP/IP                 Section 5.8    105
  2430.  
  2431.  
  2432.  
  2433. CMD_CLEAR
  2434.     This standard command should return IOERR_NOCMD when issued to
  2435.     SANA-II device.
  2436.  
  2437. CMD_INVALID
  2438.     This standard command should return IOERR_NOCMD.
  2439.  
  2440. CMD_READ
  2441.     Get the next packet available of the requested packet type.  The data
  2442.     returned (via a call to the requester-provided CopyToBuffer()
  2443.     function) is the Data Link Layer packet data only.  Raw packets are
  2444.     not supported.
  2445.  
  2446. CMD_RESET
  2447.     This standard command should return IOERR_NOCMD when issued to
  2448.     SANA-II device.
  2449.  
  2450. CMD_START
  2451.     This standard command should return IOERR_NOCMD when issued to
  2452.     SANA-II device.
  2453.  
  2454. CMD_STOP
  2455.     This standard command should return IOERR_NOCMD when issued to
  2456.     SANA-II device.
  2457.  
  2458. CMD_UPDATE
  2459.     This standard command should return IOERR_NOCMD when issued to
  2460.     SANA-II device.
  2461.  
  2462. CMD_WRITE
  2463.     Send packet to the network.  Raw packets are not supported.  Sending
  2464.     packet with a broadcast hardware address is not supported.
  2465.  
  2466. S2_BROADCAST
  2467.     Broadcast a packet to the network.  Raw packets are not supported.
  2468.  
  2469. S2_CONFIGINTERFACE
  2470.     Configure the interface.  The address field will be set depending on
  2471.     the specified hardware type.
  2472.  
  2473. S2_DEVICEQUERY
  2474.     Report the statistical information about the device.
  2475.  
  2476. S2_GETGLOBALSTATS
  2477.     Report accumulated statistics as defined in struct Sana2Devicestats.
  2478.  
  2479. S2_GETSTATIONADDRESS
  2480.     Report the ``hardware'' address for the unit.  Before the
  2481.     configuration, the current hardware address has all bits set.  The
  2482.     default hardware address is not stored anywhere.
  2483.  
  2484. S2_GETTYPESTATS
  2485.     Report accumulated statistics of the tracked packets.
  2486.  
  2487. S2_OFFLINE
  2488.     Remove interface from service.  Flush all queued IO requests.
  2489.  
  2490.  
  2491. 106    Section 5.8                 AmiTCP/IP                  System Manual
  2492.  
  2493.  
  2494.  
  2495. S2_ONEVENT
  2496.     Return when specified event(s) occur(s).
  2497.  
  2498. S2_ONLINE
  2499.     Put the interface back in service.  This command resets the unit
  2500.     statistics.
  2501.  
  2502. S2_READORPHAN
  2503.     If there is no pending CMD_READ request with the type of the received
  2504.     packet, the packet is given to first pending S2_READORPHAN request.
  2505.     The data returned (via a call to the requester-provided CopyToBuffer
  2506.     function) is the Data Link Layer packet data only.  Raw packets are
  2507.     not supported.
  2508.  
  2509. S2_TRACKTYPE
  2510.     Start tracking of the specified packet type packets.
  2511.  
  2512. S2_UNTRACKTYPE
  2513.     Stop tracking of the specified packet type packets.
  2514.  
  2515.  
  2516.  
  2517. Uninplemeted IO Commands
  2518.  
  2519. These SANA-II device commands are not supported.
  2520.  
  2521. CMD_FLUSH
  2522.     This standard command returns IOERR_NOCMD when issued to the
  2523.     agnet.device.
  2524.  
  2525. S2_ADDMULTICASTADDRESS
  2526.     This SANA-II command is not supported.  It returns IOERR_NOCMD.
  2527.  
  2528. S2_DELMULTICASTADDRESS
  2529.     This SANA-II command is not supported.  It returns IOERR_NOCMD.
  2530.  
  2531. S2_GETSPECIALSTATS
  2532.     This SANA-II command is not fully supported.  It returns an empty
  2533.     Sana2SpecialStat structure.
  2534.  
  2535.     This command should report accumulated driver specific statistics.
  2536.     This includes ethernet ``retries''.
  2537.  
  2538. S2_MULTICAST
  2539.     This SANA-II command is not supported.  It returns IOERR_NOCMD.
  2540.  
  2541.  
  2542.  
  2543. 5.8.2   Initialization Procedure
  2544.  
  2545. agnet.device must be started as a DOS process by the Run command.  The
  2546. dynamic loading is not yet implemented.  Its own startup module, init.c,
  2547. opens needed libraries, initializes device base and calls the main()
  2548. function.  Main function opens timer.device and initializes the ARexx
  2549. port; if initialization was successful,it adds the device base to the
  2550. system list.
  2551.    In the main loop the device task waits for three different events:
  2552. user or Expunge() generated break signal(SIGF _BREAK_F), ARexx messages or
  2553. user IO request messages.
  2554.  
  2555.  
  2556. System Manual                  AmiTCP/IP                 Section 5.8    107
  2557.  
  2558.  
  2559.  
  2560. 5.8.3   TheDevice Interface Functions
  2561.  
  2562. The device interface contains 6 standardlibrary calls in the device
  2563. base.  The device may be opened or closed, the IO requests may be
  2564. initiated or aborted and the system mayreclaim storage allocated by the
  2565. device driver.
  2566.    These library calls are not normally executed directly by the user code
  2567. but instead higher level convenience functions in the Exec.  The device
  2568. base library calls are made in the context of the caller, so some
  2569. synchronous IO commands may be executedlike library calls without
  2570. message passing overhead (quick IO).
  2571.    The synopsis of the functions specifies the registers where the call
  2572. parameters are passed (REG(rn)).
  2573.  
  2574.  
  2575.  
  2576. Opening an Unit
  2577.  
  2578. An IO device is opened by the Exec function call OpenDevice().  When Exec
  2579. has found the named device driver in thesystem list it calls the special
  2580. DevOpen() function from the device base.  DevOpen() function has
  2581. following synopsis:
  2582.  
  2583. ULONG ASM DevOpen(REG(a1) struct IOSana2Req *ios2,
  2584.                    REG(d0) ULONG unit, REG(d1) ULONG flags)
  2585.  
  2586.  
  2587.  
  2588.     The device open function tries to allocate and initialize various
  2589.     resources for the specified unit if the unit does not already exist.
  2590.     The initialization routine InitUnit() is called; if it returns an
  2591.     unit structure, a private buffermanagement structure is filled from
  2592.     the user provided tag list.  The user supplied IO request is filled
  2593.     with appropriate values.
  2594.  
  2595.     The promiscuous or exclusive modes are not supported.
  2596.  
  2597. struct AgnetDevUnit *InitUnit(ULONG);
  2598.  
  2599.     The initialization routine allocates an unit structure and then calls
  2600.     the configuration routine ReadConfig().  If the configuration file
  2601.     was read and interpreted without errors the lists and locks in the
  2602.     unit structure is initialized.  The unit is then put online and unit
  2603.     structure is added to the device base.
  2604.  
  2605. BOOL ReadConfig(struct AgnetDevUnit *adu)
  2606.  
  2607.     The configuration routine attempts to read in the configuration file
  2608.     for the given unit.  It strips the comments out of the file and
  2609.     provides the file as a single line to the parsing routine
  2610.     ParseConfig().  If there is no configuration file, the parsing
  2611.     routine is called with an empty line.
  2612.  
  2613.  
  2614.  
  2615. Closing an Unit
  2616.  
  2617. The accessed unit is closed after use with the Exec CloseDevice()
  2618. function.  It runs the DevClose() function from the device base.  The
  2619. call has the following synopsis:
  2620.  
  2621.  
  2622. 108    Section 5.8                 AmiTCP/IP                  System Manual
  2623.  
  2624.  
  2625.  
  2626. BPTR ASM DevClose(REG(a1) struct IOSana2Req *ios2)
  2627.  
  2628.     The device close function calls the unit close function.  If the
  2629.     device has been asked to Expunge() itself, the close function sends
  2630.     an appropriate signal to the device task.  The device task then
  2631.     performs the postponed expunge function.
  2632.  
  2633.     The DevOpen() and DevClose() calls are executed while Forbid()'den
  2634.     unless the code explicitly Wait()'s.
  2635.  
  2636.  
  2637.  
  2638. Initiating an IO Request
  2639.  
  2640.  
  2641. The DevBeginIO function from the devicebase is called to initiate an IO
  2642. command.  This call is made in the context of the requesting task (task
  2643. calling Exec functions DoIO() or SendIO()).   The DevBeginIO() call has
  2644. the following synopsis:
  2645.  
  2646.  
  2647. VOID ASM DevBeginIO(REG(a1) struct IOSana2Req *ios2)
  2648.  
  2649.     The IO request is sent to the device task for dispatching and
  2650.     execution.  Currently all IO requests are executed in the context of
  2651.     the device task, i.e.  no quick IO is supported.
  2652.  
  2653.  
  2654.  
  2655. Aborting an IO Request
  2656.  
  2657.  
  2658. Some IO requests may be aborted before they are completed by Exec
  2659. function call AbortIO().  The aborting function has thefollowing
  2660. synopsis:
  2661.  
  2662.  
  2663. VOID ASM DevAbortIO(REG(a1) struct IOSana2Req *ios2)
  2664.  
  2665.     Currently only the CMD_READ, S2_READORPHAN, CMD_WRITE, S2_BROADCAST,
  2666.     and S2_ONEVENT IO commands may be aborted.  Other IO commands are
  2667.     executed in an atomic way and can not be aborted reliably.
  2668.  
  2669.  
  2670.  
  2671. Expunging the Device
  2672.  
  2673.  
  2674. The system may reclaim the storage allocated by the device driver by
  2675. calling the DevExpunge() function.  Memory reclaiming is normally done in
  2676. a low memory situation or after a user requested memory flush.  The
  2677. expunging function has the following synopsis:
  2678.  
  2679.  
  2680. VOID ASM DevExpunge(VOID)
  2681.  
  2682.     The DevExpunge() may not Wait() because it may be called from the
  2683.     Exec function AllocMem() protected by Forbid()/Permit() pair.
  2684.  
  2685.     The DevExpunge() function call currently signals the device task,
  2686.     which performs the actual expunging by calling the DoExpunge().  Each
  2687.     unit structure is expunged by the function ExpungeUnit().
  2688.  
  2689.  
  2690. System Manual                  AmiTCP/IP                 Section 5.8    109
  2691.  
  2692.  
  2693.  
  2694. 5.8.4   Packet  Delivery
  2695.  
  2696. The packet sent to the pseudo network may be delayed or mutated randomly.
  2697. A special structure (struct DelayRequest) stores the packet type and data
  2698. during the ``transmit delay''.  The delay is implemented by sending this
  2699. structure as a the timer IO request to the timer device.  The packet
  2700. transmit functions are as follows:
  2701.  
  2702.  
  2703. VOID WritePacket(struct AgnetDevUnit *adu, struct IOSana2Req *ios2)
  2704.  
  2705.     The function checks that the unit is on line and checks for the legal
  2706.     data length.  Then the routine adds the given IO request (CMD_WRITE,
  2707.     S2_BROADCAST) into send queue.  If there is a free delay request the
  2708.     SendPacket() is called immediately.
  2709.  
  2710. VOID SendPacket(struct DelayRequest *delayed)
  2711.  
  2712.     The SendPacket() function takes an empty DelayRequest structure as
  2713.     its argument.  First, it gets a send IO request from the send queue.
  2714.     The request is immediately returned if the packet is ``lost'' during
  2715.     transmit.  This is repeated until a packet is found which is not to
  2716.     be lost.
  2717.  
  2718.     The packet data, type, length, transmission type and the address of
  2719.     the sender are then copied into the DelayRequest structure.  If
  2720.     needed, bit errors are made into packet data.
  2721.  
  2722.     If there is specified delay for the unit, the request is sent to the
  2723.     timer device.  After the delay the timer device returns request into
  2724.     the device port and it is dispatched by the ReceivePacket() function.
  2725.     If there is no delay, the ReceivePacket() is called immediately.
  2726.  
  2727. VOID ReadPacket(struct AgnetDevUnit *adu, struct IOSana2Req *ios2)
  2728.  
  2729.     The function checks that unit is online, then adds the read request
  2730.     into an appropriate queue.
  2731.  
  2732. VOID ReceivePacket(struct DelayRequest *delayed)
  2733.  
  2734.     The ReceivePacket() function calls the DoReceive() function on each
  2735.     unit the packet is destined.  It then handles the DelayRequest
  2736.     structure back to the SendPacket() function.
  2737.  
  2738. VOID DoReceive(struct AgnetDevUnit *adu,struct DelayRequest *delayed)
  2739.  
  2740.     The DoReceive() function tries to find a receive IO message waiting
  2741.     for this particular type packets.  If none is found, the first
  2742.     S2_READORPHAN IO request is selected.
  2743.  
  2744.     The CopyBack() function sets the appropriate IO request return values
  2745.     and copies the packet data to the receive buffer.
  2746.  
  2747.  
  2748.  
  2749. 5.8.5   Arexx  Interface
  2750.  
  2751. The ARexx interface is implemented by using the SimpleRexx package
  2752. provided in Commodore Native Developer Update 2.0 kit.  The Arexx
  2753. commands executed by the agnet.device are described in section 1.7.1,
  2754. page 12.
  2755.  
  2756.  
  2757. 110    Section .0                  AmiTCP/IP                   System Manual
  2758.  
  2759.  
  2760.  
  2761. LONG ParseRexx(UBYTE *arg, UBYTE **errstr, UBYTE **result)
  2762.  
  2763.     The ARexx command string is copied into a buffer and passed to the
  2764.     parser function ParseRexx().
  2765.  
  2766.     The parser allocates a DOS struct RDArgs structure for the ARexx
  2767.     command.  This structure holds the information for the DOS parsing
  2768.     functions.  The first keyword in the string is read and tokenized by
  2769.     the DOS functions ReadItem() and FindArg().
  2770.  
  2771.     The rest of the line is parsed according this token.  In the case of
  2772.     Query and Unit commands the unit number is read from the command line
  2773.     and the rest of the line is passed to the appropriate functions.
  2774.  
  2775. LONG ParseConfig(struct AgnetDevUnit *adu, struct RDArgs *rdargs,
  2776.                        STRPTR *errormessage)
  2777.     The command line stored into the RDArgs structure is parsed by the
  2778.     DOS function ReadArgs().  The parsed configuration information are
  2779.     then gathered, its legality is checked and it is stored into the unit
  2780.     structure.
  2781.  
  2782. LONG ParseQuery(struct AgnetDevUnit *adu, struct RDArgs *rdargs,
  2783.                       STRPTR *errstr, STRPTR *result)
  2784.     Like the ParseConfig(), ParseQuery() parses the command line by the
  2785.     ReadArgs().  It then fills the reply buffer by the requested
  2786.     configuration parameter values and then makes an ARexx string out of
  2787.     the buffer.  This string is then returned to the ARexx process.
  2788.